c# - 您如何遍历类的属性?

标签 c# reflection

C# 中有没有一种方法可以循环访问类的属性?

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

手动将每个值附加到字符串的明显方法,但是有没有一种方法可以有效地遍历结果对象并依次为每个属性添加值?

最佳答案

当然;您可以通过多种方式做到这一点;从反射开始(注意,这有点慢——不过对于中等数量的数据来说还可以):

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

但是;对于大量数据,值得提高效率;例如,我在这里使用 Expression API 来预编译一个看起来写入每个属性的委托(delegate) - 这里的优点是没有在每行的基础上进行反射(这对于大型数据量):

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();
}

关于c# - 您如何遍历类的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4276566/

相关文章:

java - 在运行时读取所有用特定注解装饰的类

c# .net xpath 遍历时不挑选元素

c# - WCF - 如何从基类型向客户端公开强类型对象(无需客户端转换?)

c# - 在 .Net Winforms 中使用打印预览

c# - 递归遍历对象的属性抛出 StackOverflowException

c# - 通过反射按自定义属性对实体进行 Linq 排序

c# - 实例化所有实现通用接口(interface)实例的类

c# - 获取对象的属性名称和它期望的类型

c# - 无注释的protobuf-net序列化

c# - 如何将许多字符的组合更改为其中一种