Как я могу найти все открытые поля объекта в C#?

Я создаю метод, чтобы взять 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. Я исправлю это позже - прямо сейчас мне просто интересно, как получить все общедоступные поля, связанные с объектом.

5 ответов


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 для работы ; -)


Вы можете получить все поля объекта, объявленные непосредственно в классе с помощью BindingFlags:

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

и все поля объекта, включая унаследованные с:

GetFields(BindingFlags.Public | BindingFlags.Instance)

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 в полях не требуется как тип.GetFields (), как определено MSDN гласит:

Возвращаемое Значение - система типов.Отображение.Объект fieldinfo[]

массив объектов FieldInfo, представляющих все общественные поля определено для текущего типа.


конечно, другой вопрос: "почему у вас есть публичные поля?"- предпочтительнее свойства. В качестве абстракции обратите внимание, что отражение-не единственный вариант: Тип также может раскрывать свои свойства "на лету" во время выполнения (например, как нетипизированный DataTable/DataView предоставляет столбцы как свойства).

чтобы поддержать это (в то же время поддерживая простые объекты), вы бы использовали TypeDescriptor:

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

Это также позволяет для многочисленной расширяемости варианты-например, vastly ускорение отражения (без изменения кода).


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