2012-03-27 20 views
56

Tengo una clase que contiene varias propiedades (todas son cadenas si hace alguna diferencia).
También tengo una lista, que contiene muchas instancias diferentes de la clase.C# foreach (propiedad en el objeto) ... ¿Hay una manera simple de hacer esto?

bien la creación de algunas pruebas unitarias para mis clases decidí que quería colocar a través de cada objeto en la lista y luego bucle a través de cada propiedad de ese objeto ...

pensé hacerlo sería tan simple como. ..

foreach (Object obj in theList) 
{ 
    foreach (Property theProperties in obj) 
    { 
     do some stufff!!; 
    } 
} 

Pero esto no funcionó! :( me sale este error ...

"instrucción foreach no puede operar en variables de tipo 'Application.Object' porque 'Application.Object' no contiene una definición pública de 'GetEnumerator'"

¿El alguien sabe de una manera de hacer esto sin toneladas de IFS y bucles o sin meterse en algo demasiado complejo

+4

En el futuro, no diga "No funciona" en una pregunta. En su lugar, especifique el problema que está teniendo (error de compilación, etc.). ¡Gracias! –

+0

¡Actualizado! Gracias por el aviso Robert – Jammerz858

Respuesta

91

probar esto:?

foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties()) 
{ 
    // do stuff here 
} 

también tenga en cuenta que Type.GetProperties() tiene una sobrecarga de los cuales acepta un conjunto de banderas de encuadernación para que pueda filtrar las propiedades en un criterio diferente, como el nivel de accesibilidad; consulte MSDN para obtener más información: Type.GetProperties Method (BindingFlags) Por último, pero no menos importante, no olvide agregar la referencia de ensamblado "system.reflection".

Por ejemplo, para resolver todas las propiedades públicas:

foreach (var propertyInfo in obj.GetType() 
           .GetProperties(
             BindingFlags.Public 
             | BindingFlags.Instance)) 
{ 
    // do stuff here 
} 

Por favor, hágamelo saber si esto funciona como se esperaba.

+1

Una vez que tenga un control sobre las propiedades de los objetos, ¿hay alguna forma de aprovechar el valor de cada propiedad? es decir, un nombre o código postal, por ejemplo, – JsonStatham

2

utilizar la reflexión para hacer esto

SomeClass A = SomeClass(...) 
PropertyInfo[] properties = A.GetType().GetProperties(); 
12

Your'e casi allí, sólo tiene que obtener las propiedades del tipo, en lugar de esperar que las propiedades sean accesibles en forma de una bolsa de recolección o la propiedad :

var property in obj.GetType().GetProperties() 

A partir de ahí you can access like so:

property.Name 
property.GetValue(obj, null) 

Wi th GetValue el segundo parámetro le permitirá especificar valores de índice, que funcionarán con las propiedades que devuelven colecciones: dado que una cadena es una colección de caracteres, también puede especificar un índice para devolver un carácter si es necesario.

+0

¿molesté a alguien? Estoy abierto a saber qué pasa con esto, de lo contrario quizás nunca aprenda. –

+0

Probablemente recibiste el downvote cuando tu código estaba equivocado (antes de tu edición ninja). –

13

Claro, no hay problema:

foreach(object item in sequence) 
{ 
    if (item == null) continue; 
    foreach(PropertyInfo property in item.GetType().GetProperties()) 
    { 
     // do something with the property 
    } 
} 
+0

¿por qué agregaste esta línea? 'if (item == null) continue;' personalmente, creo que si obtienes un objeto nulo en ese punto, algo salió mal mucho antes y ahí es donde debería estar la validación, ¿o estoy equivocado? – Dementic

+0

@Dementic: Claro, podríamos decir que se requiere que la secuencia contenga referencias no nulas. –

20

Puede recorrer todas las propiedades no indexadas de un objeto como este:

var s = new MyObject(); 
foreach (var p in s.GetType().GetProperties().Where(p => !p.GetGetMethod().GetParameters().Any())) { 
    Console.WriteLine(p.GetValue(s, null)); 
} 

Desde GetProperties() vuelve indexadores, así como propiedades simples, necesita un filtro adicional antes de llamar al GetValue para saber que es seguro pasar null como el segundo parámetro.

Es posible que tenga que modificar el filtro aún más para eliminar las propiedades de solo escritura y de otro modo inaccesibles.

+0

+1 solo por hacer algo con las propiedades que realmente se pueden usar; también es posible que desee filtrar las propiedades de solo escritura. – hvd

+0

@hvd ¡Es un excelente punto en las propiedades de solo escritura! Casi me he olvidado de ellos. Mi código se bloqueará si encuentra una propiedad con 'null' getter, pero estoy seguro de que OP averiguará cómo obtener solo las propiedades que necesita. – dasblinkenlight

+1

votado para mostrar cómo obtener el valor –

0

Una pequeña advertencia, si "hacer algunas cosas" significa actualizar el valor de la propiedad real que visita Y si hay una propiedad de tipo de estructura a lo largo de la ruta desde el objeto raíz a la propiedad visitada, el cambio que realizó en la propiedad no se reflejará en el objeto raíz.

Cuestiones relacionadas