2008-10-26 5 views
13

Je suis en train de construire une méthode pour prendre dans une ArrayList (vraisemblablement plein d'objets) et ensuite lister tous les champs (et leurs valeurs) pour chaque objet dans la ArrayList.Comment trouver tous les champs publics d'un objet en C#?

Actuellement, mon code est le suivant:

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

     } 
    } 

Bien sûr, je comprends la question immédiate avec ce code: si cela fonctionnait, il avait seulement imprimer un champ par objet dans le ArrayList. Je vais corriger cela plus tard - en ce moment je suis juste curieux de savoir comment obtenir tous les champs publics associés à un objet.

EDIT: Désolé pour les réponses de flip-flopping tellement. J'aurais dû essayer chaque méthode avant de choisir une réponse.

+0

Votre code affichera: System.Reflection.FieldInfo [] –

Répondre

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

Notez que ce code nécessite .NET 3.5 pour travailler ;-)

+0

Nevermind. J'aime mieux cette technique. Je peux juste extrapoler ceci pour obtenir des propriétés (et même des méthodes) aussi bien. Merci beaucoup! – junkforce

+1

Thx pour la condition .where Dave .. Je sais que c'est 10 ans plus tard mais j'aime ça. Simple .. public seulement .. pas besoin de getetters .. et ne vous inquiétez pas, il fonctionne toujours avec C# dans VS 2017 .net 4.6.2 et core: 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)); 
     } 
    } 
} 

Je voudrais mentionner que la recherche de IsPublic dans les champs n'est pas nécessaire que type.GetFields() comme définie par MSDN états:

valeur de retour - type: System.Reflection.FieldInfo []

Un tableau d'objets FieldInfo représentant tous les champs publics définis pour le type actuel.

+0

Quels espaces de noms sont PropertyInfo et FieldInfo? – 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

Vous pouvez obtenir tous les objets champs déclarés directement dans la classe avec les BindingFlags:

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

et tous les champs d'objets y compris hérités avec:

GetFields(BindingFlags.Public | BindingFlags.Instance) 
1

Bien sûr, une autre question serait "pourquoi avez-vous des champs publics?" - les propriétés étant préférables. Comme une abstraction, notez que la réflexion n'est pas la seule option: il est également possible pour un type d'exposer ses propriétés à la volée au moment de l'exécution (comme un DataTable/DataView non typé expose des colonnes en tant que propriétés).

Pour soutenir cette approche (tout en soutenant des objets simples), vous devez utiliser TypeDescriptor:

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

Cela permet également de nombreuses options d'extensibilité - par exemple, largement speeding up reflection (sans changer de code).

+0

Pretty.Cela m'a permis de faire un ToString général() pour une superclasse abstraite qui montre deux propriétés ("Key" et "Code" - était une classe d'objets de base de données) que la plupart de ses sous-classes contiennent, sans avoir besoin d'informations spécifiques sur lesdites sous-classes :) – Nyerguds

Questions connexes