Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
460 views
in Technique[技术] by (71.8m points)

c# - How can you loop over the properties of a class?

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 a large database query). I need to output these results as a CSV file so need to append each value to a string.

The obvious way it to manually append each value to a string, but is there a way to effectively loop over the results object and add the value for each property in turn?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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<T>(IEnumerable<T> 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<Func<StringBuilder, T, StringBuilder>>(body, sb, obj);
    var func = lambda.Compile();

    var result = new StringBuilder();
    foreach (T row in data)
    {
        func(result, row);
    }
    return result.ToString();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...