How can you loop over the properties of a class?

后端 未结 11 1564
温柔的废话
温柔的废话 2020-11-29 23:37

Is there a way in c# to loop over the properties of a class?

Basically I have a class that contains a large number of property\'s (it basically holds the results of

11条回答
  •  暖寄归人
    2020-11-30 00:10

    Sure; you can do that in many ways; starting with reflection (note, this is slowish - OK for moderate amounts of data though):

    var props = objectType.GetProperties();
    foreach(object obj in data) {
        foreach(var prop in props) {
            object value = prop.GetValue(obj, null); // against prop.Name
        }
    }
    

    However; for larger volumes of data it would be worth making this more efficient; for example here I use the Expression API to pre-compile a delegate that looks writes each property - the advantage here is that no reflection is done on a per-row basis (this should be significantly faster for large volumes of data):

    static void Main()
    {        
        var data = new[] {
           new { Foo = 123, Bar = "abc" },
           new { Foo = 456, Bar = "def" },
           new { Foo = 789, Bar = "ghi" },
        };
        string s = Write(data);        
    }
    static Expression StringBuilderAppend(Expression instance, Expression arg)
    {
        var method = typeof(StringBuilder).GetMethod("Append", new Type[] { arg.Type });
        return Expression.Call(instance, method, arg);
    }
    static string Write(IEnumerable data)
    {
        var props = typeof(T).GetProperties();
        var sb = Expression.Parameter(typeof(StringBuilder));
        var obj = Expression.Parameter(typeof(T));
        Expression body = sb;
        foreach(var prop in props) {            
            body = StringBuilderAppend(body, Expression.Property(obj, prop));
            body = StringBuilderAppend(body, Expression.Constant("="));
            body = StringBuilderAppend(body, Expression.Constant(prop.Name));
            body = StringBuilderAppend(body, Expression.Constant("; "));
        }
        body = Expression.Call(body, "AppendLine", Type.EmptyTypes);
        var lambda = Expression.Lambda>(body, sb, obj);
        var func = lambda.Compile();
    
        var result = new StringBuilder();
        foreach (T row in data)
        {
            func(result, row);
        }
        return result.ToString();
    }
    

提交回复
热议问题