你怎么能循环一个类的​​属性?

Ser*_*gio 51 c# reflection

在c#中有一种方法可以循环遍历类的属性吗?

基本上我有一个包含大量属性的类(它基本上保存了大型数据库查询的结果).我需要将这些结果输出为CSV文件,因此需要将每个值附加到字符串.

显然,它可以手动将每个值附加到字符串,但有没有办法有效地循环结果对象并依次为每个属性添加值?

Mar*_*ell 53

当然; 你可以通过多种方式做到这一点; 从反射开始(注意,这很慢 - 虽然适用于适量的数据):

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

然而; 对于更大量的数据,值得提高效率; 例如,我在这里使用ExpressionAPI来预编译一个看起来写入每个属性的委托 - 这里的优点是不会对每行进行反射(对于大量数据,这应该明显更快):

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();
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*ven 20

foreach (PropertyInfo prop in typeof(MyType).GetProperties())
{
    Console.WriteLine(prop.Name);
}
Run Code Online (Sandbox Code Playgroud)


Aar*_*ron 5

我在这个页面上尝试了各种推荐,但我无法让它们起作用.我从最顶层的答案开始(你会注意到我的变量同样被命名),并且我自己完成了它.这就是我的工作 - 希望它可以帮助别人.

var prop = emp.GetType().GetProperties();     //emp is my class
    foreach (var props in prop)
      {
        var variable = props.GetMethod;

        empHolder.Add(variable.Invoke(emp, null).ToString());  //empHolder = ArrayList
      }
Run Code Online (Sandbox Code Playgroud)

***我应该提到这只会在你使用get; set; (公共)财产.