20

我正在构建一个方法来获取一个 ArrayList(可能是满的对象),然后列出 ArrayList 中每个对象的所有字段(及其值)。

目前我的代码如下:

public static void ListArrayListMembers(ArrayList list)
    {
        foreach (Object obj in list)
        {
            Type type = obj.GetType();
            string field = type.GetFields().ToString();
            Console.WriteLine(field);

        }
    }

当然,我理解这段代码的直接问题:如果它有效,它只会在 ArrayList 中为每个对象打印一个字段。我稍后会解决这个问题 - 现在我只是好奇如何获取与对象关联的所有公共字段。

4

5 回答 5

34
foreach (Object obj in list) {
    Type type = obj.GetType();

    foreach (var f in type.GetFields().Where(f => f.IsPublic)) {
        Console.WriteLine(
            String.Format("Name: {0} Value: {1}", f.Name, f.GetValue(obj));
    }                           
}

请注意,此代码需要 .NET 3.5 才能工作;-)

于 2008-10-26T00:42:03.983 回答
10

您可以使用 BindingFlags 获取直接在类中声明的所有对象字段:

GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)

和所有对象字段,包括继承:

GetFields(BindingFlags.Public | BindingFlags.Instance)
于 2008-10-26T01:09:15.723 回答
4
public static void ListArrayListMembers(ArrayList list)
{
    foreach (Object obj in list)
    {
        Type type = obj.GetType();
        Console.WriteLine("{0} -- ", type.Name);
        Console.WriteLine(" Properties: ");
        foreach (PropertyInfo prop in type.GetProperties())
        {
            Console.WriteLine("\t{0} {1} = {2}", prop.PropertyType.Name, 
                prop.Name, prop.GetValue(obj, null));
        }
        Console.WriteLine(" Fields: ");
        foreach (FieldInfo field in type.GetFields())
        {
            Console.WriteLine("\t{0} {1} = {2}", field.FieldType.Name, 
                field.Name, field.GetValue(obj));
        }
    }
}

我想提一下,不需要在字段中查找 IsPublic,因为 type.GetFields() 正如MSDN所定义的那样:

返回值 - 类型:System.Reflection.FieldInfo[]

FieldInfo 对象数组,表示为当前类型定义的所有公共字段。

于 2008-10-26T00:54:50.153 回答
4

当然,另一个问题是“你为什么有公共领域?” - 属性更可取。作为抽象,请注意反射不是唯一的选择:类型也可以在运行时即时公开其属性(例如无类型DataTable/如何DataView将列公开为属性)。

为了支持这一点(同时也支持简单对象),您将使用TypeDescriptor

        foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
        {
            Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
        }

这也允许许多可扩展性选项 - 例如,大大加快反射速度(无需更改任何代码)。

于 2008-10-26T10:09:02.810 回答
1
    static void ListArrayListMembers(ArrayList list)
    {
        foreach (object obj in list)
        {
            Type type = obj.GetType();
            foreach (FieldInfo field in type.GetFields(BindingFlags.Public))
            {
                Console.WriteLine(field.Name + " = " + field.GetValue(obj).ToString());
            }
        }
    }
于 2008-10-26T00:56:53.753 回答