2010-04-22 14 views
12

¿Cuál es la mejor manera de hacerlo en C#?C# - Valores de propiedades recursivas/de reflexión

string propPath = "ShippingInfo.Address.Street"; 

Voy a tener una ruta de propiedad como la de arriba leída de un archivo de mapeo. Necesito poder preguntar al objeto Order cuál será el valor del código siguiente.

this.ShippingInfo.Address.Street 

Equilibrio de rendimiento con elegancia. Todas las relaciones de gráficos de objetos deben ser uno a uno. Parte 2: qué tan difícil sería agregar la capacidad de capturar el primero si es una lista <> o algo así.

Respuesta

25

Quizás algo como esto?

string propPath = "ShippingInfo.Address.Street"; 

object propValue = this; 
foreach (string propName in propPath.Split('.')) 
{ 
    PropertyInfo propInfo = propValue.GetType().GetProperty(propName); 
    propValue = propInfo.GetValue(propValue, null); 
} 

Console.WriteLine("The value of " + propPath + " is: " + propValue); 

O, si lo prefiere LINQ, puede probar esto en su lugar. (Aunque personalmente prefiero la versión que no es LINQ.)

string propPath = "ShippingInfo.Address.Street"; 

object propValue = propPath.Split('.').Aggregate(
    (object)this, 
    (value, name) => value.GetType().GetProperty(name).GetValue(value, null)); 

Console.WriteLine("The value of " + propPath + " is: " + propValue); 
+0

+1 porque el ejemplo de código es más corto que su descripción textual * g * – Foxfire

+0

Me gusta. Me corrigen las dificultades de expresar esto.Aplicación Cool LINQ también. – kmontgom

1

suena como una serie de invocaciones de propiedad anidados:

clase X tiene una propiedad llamada ShippingInfo; el tipo representado por ShippingInfo tiene una dirección de propiedad; el tipo representado por Dirección tiene una propiedad llamada Calle.

Así, en el supuesto de que sabe la instancia apropiada de la clase X para operar en: ("". ToCharArray())

  • tokenize la cadena a través de string.split a una cadena [], o algo al igual que
  • comienzo con el caso conocido de X
  • utilizar la reflexión para obtener el MethodInfo para el captador ShippingInfo
  • utilizar la reflexión para obtener el tipo devuelto por ShippingInfo get()
  • invocar la getter utilizando la reflexión
  • usando el valor de retorno de la ShippingInfo get() y el tipo de la devolución:
    • obtener el MethodInfo para el captador de direcciones en el tipo devuelto .....

y así sucesivamente. Te dan la imagen.

Parece un poco largo y tedioso, y lo es. Pero así es como lo harías a través de la reflexión.

Me pregunto si es posible hacer lo mismo con LINQ to Objects?

La respuesta a la parte 2 implica obtener el valor inicial de X de su lista <>.

+0

¿Puede por favor reescribir esto? No es muy fácil de entender - demasiadas palabras :) – Nayan

+0

No. En todo caso, es demasiado breve y corto de detalles. Ese es el problema con algo como la reflexión, hay muchos pasos y cada paso requiere conocimientos específicos. Lo siento. – kmontgom

Cuestiones relacionadas