你怎么能遍历一个类的属性? [英] How can you loop over the properties of a class?
问题描述
有没有在C#的方式来遍历一个类的属性?
Is there a way in c# to loop over the properties of a class?
基本上我有一个包含大量的类属性的(它基本上拥有一个庞大的数据库查询的结果)。
我需要输出这些结果为CSV文件,所以需要每个值追加到一个字符串。
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?
推荐答案
当然,你可以这样做在很多方面;开始反思(注意,这是slowish - 适用于中度的数据虽然):
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
}
}
不过,对于较大的数据量将是值得的这种更有效的;例如,在这里我使用了防爆pression
API为pre-编译的委托,看起来写入每个属性 - 这里的优点是无反射是在做每行的基础上(这应该是大容量的数据的显著更快):
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();
}
这篇关于你怎么能遍历一个类的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!