2010-05-26 33 views
9

Este es un escenario creado para ayudar a entender lo que estoy tratando de lograr.C# Uso de la reflexión para obtener propiedades de un objeto genérico (y sus objetos anidados)

Estoy tratando de crear un método que devuelve la propiedad especificada de un objeto genérico

por ejemplo,

public object getValue<TModel>(TModel item, string propertyName) where TModel : class{ 
    PropertyInfo p = typeof(TModel).GetProperty(propertyName); 
    return p.GetValue(item, null); 
} 

El código anterior funciona bien si usted está buscando una propiedad en la TModel item por ejemplo,

string customerName = getValue<Customer>(customer, "name"); 

Sin embargo, si usted quiere saber lo que el nombre del grupo del cliente es, se convierte en un problema: por ejemplo,

string customerGroupName = getValue<Customer>(customer, "Group.name"); 

Esperando que alguien pueda darme una idea sobre este escenario de salida - gracias.

Respuesta

3

En el espacio de nombres System.Web.UI hay un método para hacer eso:

DataBinder.Eval(source, expression); 
+0

UBER Legend ...! – Jimbo

+0

Buena captura. El único "problema" que tengo con este es que depende de System.Web.dll –

+0

Sí, probablemente debería ir a otro ensamblaje – Guillaume86

3

Te estoy adivinando sólo hay que descomponerlo en un par de pasos en lugar de intentar hacerlo todo en uno, algo así como:

// First get the customer group Property... 
CustomerGroup customerGroup = getValue<Customer>(customer, "Group"); 
// Then get the name of the group... 
if(customerGroup != null) 
{ 
    string customerGroupName = getValue<CustomerGroup>(customerGroup, "name"); 
} 
0

Desde Grupo es propiedad del cliente, lo cual en sí mismo aloja el nombre de la propiedad, tienes que ir por este camino también. Pero desde '.' No puede ser parte del nombre de la propiedad; puede usar String.Substring para eliminar el primer nombre de propiedad de la cadena y llamar a su método recursivamente.

11

Aquí hay un método simple que usa recursividad para resolver su problema. Le permite recorrer un gráfico de objetos pasando un nombre de propiedad "punteado". Funciona con propiedades y campos.

static class PropertyInspector 
{ 
    public static object GetObjectProperty(object item,string property) 
    { 
     if (item == null) 
      return null; 

     int dotIdx = property.IndexOf('.'); 

     if (dotIdx > 0) 
     { 
      object obj = GetObjectProperty(item,property.Substring(0,dotIdx)); 

      return GetObjectProperty(obj,property.Substring(dotIdx+1)); 
     } 

     PropertyInfo propInfo = null; 
     Type objectType = item.GetType(); 

     while (propInfo == null && objectType != null) 
     { 
      propInfo = objectType.GetProperty(property, 
         BindingFlags.Public 
        | BindingFlags.Instance 
        | BindingFlags.DeclaredOnly); 

      objectType = objectType.BaseType; 
     } 

     if (propInfo != null) 
      return propInfo.GetValue(item, null); 

     FieldInfo fieldInfo = item.GetType().GetField(property, 
         BindingFlags.Public | BindingFlags.Instance); 

     if (fieldInfo != null) 
      return fieldInfo.GetValue(item); 

     return null; 
    } 
} 

Ejemplo:

class Person 
{ 
    public string Name { get; set; } 
    public City City { get; set; } 
} 

class City 
{ 
    public string Name { get; set; } 
    public string ZipCode { get; set; } 
} 

Person person = GetPerson(id); 

Console.WriteLine("Person name = {0}", 
     PropertyInspector.GetObjectProperty(person,"Name")); 

Console.WriteLine("Person city = {0}", 
     PropertyInspector.GetObjectProperty(person,"City.Name")); 
+0

leyenda ......... – Jimbo

+0

Muchas gracias para esto, una gran pieza para aprender, sin embargo, he aceptado una respuesta que está incorporada en .NET – Jimbo

Cuestiones relacionadas