2008-10-26 4 views
13

Ich konstruiere eine Methode, um eine ArrayList (vermutlich voller Objekte) aufzunehmen und listet dann alle Felder (und ihre Werte) für jedes Objekt in der ArrayList auf.Wie kann ich alle öffentlichen Felder eines Objekts in C# finden?

Derzeit ist mein Code wie folgt:

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

     } 
    } 

Natürlich verstehe ich das unmittelbare Problem mit diesem Code: wenn sie es funktionieren nur ein Feld in der Arraylist pro Objekt gedruckt werden würde. Ich werde das später beheben - im Moment bin ich nur neugierig, wie man alle öffentlichen Felder, die mit einem Objekt verbunden sind, bekommt.

EDIT: Sorry für Flip-Flop Antworten so viel. Ich hätte jede Methode ausprobiert, bevor ich eine Antwort wählte.

+0

Ihr Code wird dies ausdrucken: System.Reflection.FieldInfo [] –

Antwort

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

Beachten Sie, dass dieser Code erfordert .NET 3.5 ;-)

+0

Nevermind. Ich mag diese Technik besser. Ich kann dies nur extrapolieren, um Eigenschaften (und sogar Methoden) zu erhalten. Vielen Dank! – junkforce

+1

Thx für die .where Zustand Dave .. Ich weiß, es ist 10 Jahre später, aber ich mag es. Unkompliziert .. nur publics .. keine Notwendigkeit für getsetters .. und keine Sorge, es funktioniert immer noch mit C# in VS 2017. Net 4.6.2 und Kern: p – Goodies

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

Ich möchte erwähnen, zu arbeiten, dass in den Bereichen für IsPublic suchen als type.GetFields nicht erforderlich ist() als definiert durch MSDN Staaten:

Rückgabewert - Typ: System.Reflection.FieldInfo []

Ein Array von Fieldinfo Objekte, die alle öffentliche Felder für den aktuellen Typ definiert.

+0

Welchen Namespace sind PropertyInfo und FieldInfo in? – junkforce

+0

System.Reflection –

+0

System.Reflection –

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

Sie erhalten alle das Objekt Felder erklärt direkt in der Klasse mit den Binding:

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

und alle Objektbereiche einschließlich geerbt mit:

GetFields(BindingFlags.Public | BindingFlags.Instance) 
1

natürlich eine andere Frage wäre "warum hast du öffentliche Felder?" - Eigenschaften sind vorzuziehen. Beachten Sie als Abstraktion, dass Reflexion nicht die einzige Option ist: Es ist auch möglich, dass ein Typ seine Eigenschaften während der Laufzeit zur Verfügung stellt (so wie ein untypisierter DataTable/DataView Spalten als Eigenschaften verfügbar macht).

Um dies zu unterstützen (während auch einfache Objekte unterstützt), können Sie TypeDescriptor verwenden würden: Auf diese Weise kann auch für zahlreiche Erweiterungsoptionen

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

- zum Beispiel in beträchtlichem Ausmaß speeding up reflection (ohne Code zu ändern).

+0

Ziemlich.Dadurch konnte ich eine allgemeine ToString() für eine abstrakte Oberklasse erstellen, die zwei Eigenschaften ("Key" und "Code" - war eine Datenbank-Objektklasse), die die meisten seiner Unterklassen enthalten, ohne dass spezifische Informationen über die Unterklassen :) – Nyerguds