2008-10-26 16 views
13

Estoy construyendo un método para tomar una ArrayList (presumiblemente llena de objetos) y luego una lista de todos los campos (y sus valores) para cada objeto en ArrayList.¿Cómo puedo encontrar todos los campos públicos de un objeto en C#?

Actualmente mi código es el siguiente:

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

     } 
    } 

Por supuesto, entiendo el problema inmediato con este código: si funcionaba sólo había imprimir un campo por objeto en el ArrayList. Lo arreglaré más tarde. Ahora mismo tengo curiosidad por saber cómo obtener todos los campos públicos asociados con un objeto.

EDIT: Perdón por las respuestas de los flip-flopping. Debería haber probado todos los métodos antes de seleccionar una respuesta.

+0

Su código se imprimirá esto: System.Reflection.FieldInfo [] –

Respuesta

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

Tenga en cuenta que este código requiere .NET 3.5 para trabajar ;-)

+0

Nevermind. Me gusta esta técnica mejor. Puedo extrapolar esto para obtener propiedades (e incluso métodos) también. ¡Gracias un montón! – junkforce

+1

Gracias por la condición de. Dave ... Sé que es 10 años después pero me gusta. Sencillo ... solo públicos ... no hay necesidad de ajustadores ... y no te preocupes, todavía funciona con C# en VS 2017 .net 4.6.2 y 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)); 
     } 
    } 
} 

me gustaría mencionar que la búsqueda de IsPublic en los campos no es necesario ya que type.GetFields() como definido por MSDN estados:

valor de retorno - Tipo: System.Reflection.FieldInfo []

matriz de objetos que representa a todos los FieldInfo campos públicos definidos para el Tipo actual.

+0

¿En qué espacios de nombre están PropertyInfo y 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

Puede obtener todos los objetos campos declarados directamente en la clase con los BindingFlags:

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

y todos los campos de objeto que incluye heredado con:

GetFields(BindingFlags.Public | BindingFlags.Instance) 
1

Por supuesto, otra cuestión sería "¿por qué tienes campos públicos?" - las propiedades son preferibles. Como abstracción, tenga en cuenta que la reflexión no es la única opción: también es posible que un tipo exponga sus propiedades sobre la marcha en tiempo de ejecución (por ejemplo, cómo un DataTable/DataView sin formato expone las columnas como propiedades).

Para apoyar esto (mientras que también soporta objetos simples), utilizaría TypeDescriptor:

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

Esto también permite numerosas opciones de extensibilidad - por ejemplo, muy speeding up reflection (sin cambiar ningún código).

+0

Pretty.Esto me permitió crear un ToString general() para una superclase abstracta que muestra dos propiedades ("Clave" y "Código" - era una clase de objetos de base de datos) que contienen la mayoría de sus subclases, sin necesidad de información específica sobre dichas subclases :) – Nyerguds

Cuestiones relacionadas