2010-05-26 10 views
9

To jest scenariusz stworzony, aby pomóc zrozumieć, co próbuję osiągnąć.C# Korzystanie z odbicia, aby uzyskać właściwości obiektu ogólnego (i jego obiektów zagnieżdżonych)

Próbuję utworzyć metodę, która zwraca określonej właściwości obiektu ogólnego

np

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

Powyższy kod działa dobrze, jeśli szukasz nieruchomości na TModel item np

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

Jednakże, jeśli chcesz dowiedzieć się, jakie nazwisko klienta grupy jest, staje się problemem: np

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

Mam nadzieję, że ktoś może dać mi wgląd w ten scenariusz - dzięki.

Odpowiedz

3

W nazw System.Web.UI istnieje metoda, aby to zrobić:

DataBinder.Eval(source, expression); 
+0

UBER Legend ...! – Jimbo

+0

Dobry połów. Jedyny "problem" jaki mam z tym jednym jest to, że to zależy od System.Web.dll –

+0

Tak, prawdopodobnie powinien przejść do innego zespołu – Guillaume86

3

Zgaduję wystarczy podzielenie go na kilka etapów, zamiast próbować zrobić to wszystko w jednym, coś takiego:

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

Ponieważ Grupa jest własnością klienta, który sama jest gospodarzem nazwy nieruchomości, musisz iść tą drogą. Ale od "." Nie może być częścią nazwy własności, możesz łatwo użyć String.Substring, aby usunąć pierwszą nazwę właściwości z ciągu i wywołać metodę rekursywnie.

11

Oto prosta metoda, która używa rekursji do rozwiązania problemu. Pozwala na przemierzanie wykresu obiektów poprzez podanie "wykropkowanej" nazwy właściwości. Działa z właściwościami i polami.

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

Przykład:

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

Legenda ......... – Jimbo

+0

dziękuję do tego świetny kawałek do nauki, jednak zaakceptowałem odpowiedź, która jest wbudowana w .NET – Jimbo

Powiązane problemy