2010-05-26 4 views
9

Dies ist ein Szenario, das erstellt wurde, um zu verstehen, was Im zu erreichen versucht.C# Verwenden von Reflection zum Abrufen der Eigenschaften eines generischen Objekts (und seiner verschachtelten Objekte)

Ich versuche, ein Verfahren zu schaffen, die

zum Beispiel die angegebene Eigenschaft eines generischen Objekt zurückgibt

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

Der obige Code funktioniert gut, wenn Sie sich für eine Immobilie auf dem TModel item zum Beispiel suchen

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

Wenn Sie jedoch wollen, um herauszufinden, was der Name des Kundengruppe ist, wird es ein Problem: z.B.

Ich hoffe, jemand kann mir einen Einblick in dieses Szenario geben - danke.

Antwort

3

Im System.Web.UI-Namespace gibt es ein Verfahren, das zu tun:

DataBinder.Eval(source, expression); 
+0

UBER Legend ... eingebaut ist! – Jimbo

+0

Guter Fang. Das einzige "Problem", das ich mit diesem habe, ist, dass es von System.Web.dll abhängt –

+0

Yeah sollte es wahrscheinlich zu einer anderen Baugruppe gehen – Guillaume86

3

Ich vermute, Sie brauchen nur diese eher von Schritten in ein Paar zu brechen als zu versuchen, wie sie alle in einem, etwas zu tun:

// 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

Seit Gruppe ist Eigentum des Kunden, die selbst beherbergt den Namen der Eigenschaft, müssen Sie auch diesen Weg gehen. Aber seit '.' Kann nicht Teil des Namens der Eigenschaft sein, Sie können String.Substring einfach verwenden, um den ersten Eigenschaftsnamen aus der Zeichenfolge zu entfernen und Ihre Methode rekursiv aufzurufen.

11

Hier ist eine einfache Methode, die Rekursion verwendet, um Ihr Problem zu lösen. Sie können ein Objektdiagramm durchlaufen, indem Sie einen "gepunkteten" Eigenschaftsnamen übergeben. Es funktioniert sowohl mit Eigenschaften als auch mit Feldern.

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

Beispiel:

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

Legend ......... – Jimbo

+0

Thanks a lot Dazu ein tolles Stück, von dem ich lernen kann, aber ich habe eine Antwort akzeptiert, die in .NET – Jimbo

Verwandte Themen