2008-10-26 2 views
13

Я строю метод, чтобы взять ArrayList (предположительно полный объектов), а затем перечислить все поля (и их значения) для каждого объекта в ArrayList.Как я могу найти все общедоступные поля объекта в C#?

В настоящее время мой код выглядит следующим образом:

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

     } 
    } 

Конечно, я понимаю, сразу же вопрос с этим кодом: если он работал, было бы печатать только одно поле для каждого объекта в ArrayList. Я исправлю это позже - прямо сейчас мне просто интересно, как получить все публичные поля, связанные с объектом.

EDIT: Извините за откидные ответы. Я должен был попробовать каждый метод, прежде чем выбирать ответ.

+0

Ваш код напечатает это: System.Reflection.FieldInfo [] – 2008-10-26 01:21:52

ответ

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

+0

Nevermind. Мне нравится эта техника лучше. Я могу просто экстраполировать это, чтобы получить свойства (и даже методы). Огромное спасибо! – junkforce 2008-10-26 01:09:01

+1

Thx для. Где бы то ни было. Дейв .. Я знаю, что это уже 10 лет, но мне это нравится. Straightforward .. только публики .. нет необходимости в getetters .. и не волнуйтесь, он по-прежнему работает с C# в VS 2017. .net 4.6.2 и ядро: p – Goodies 2018-01-05 01:56:01

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 представляющих все общедоступные поля, определенные для текущего типа.

+0

Какое пространство имен есть PropertyInfo и FieldInfo in? – junkforce 2008-10-26 01:00:51

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

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

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

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

GetFields(BindingFlags.Public | BindingFlags.Instance) 
1

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

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

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

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

Смежные вопросы