2010-05-26 66 views
9

這是創建一個場景,幫助理解我試圖實現什麼。C#使用反射來獲取通用對象的(及其嵌套對象)屬性

我試圖創建一個返回的通用對象

例如的指定屬性的方法

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

,如果你正在尋找一個屬性上TModel item 例如上面的代碼工作正常

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

不過,如果你想找出客戶的組的名稱是什麼,它成爲一個問題: 例如

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

希望有人能在這種情況下給我一些見解 - 謝謝。

回答

3

在System.Web.UI命名空間有這樣做的方法:

DataBinder.Eval(source, expression); 
+0

UBER Legend ...! – Jimbo 2010-05-26 10:04:42

+0

好的。我唯一的問題是它取決於System.Web.dll – 2010-05-26 10:07:13

+0

是的,它可能應該去其他程序集 – Guillaume86 2010-05-26 10:08:11

3

我猜你只需要打破這種分解成幾個步驟,而不是試圖做這一切在一個,是這樣的:

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

由於集團客戶,的財產本身是主機的屬性名稱,你也必須這樣做。 但自'。'不能成爲屬性名稱的一部分,你可以很容易地使用String.Substring從字符串中刪除第一個屬性名稱並遞歸地調用你的方法。

11

這是一個使用遞歸來解決問題的簡單方法。它允許您通過傳遞「虛線」屬性名稱來遍歷對象圖。它適用於屬性和字段。

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

例子:

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

傳奇......... – Jimbo 2010-05-26 10:00:09

+0

非常感謝爲此,一個偉大的部分學習,但是我已經接受了構建到.NET的答案 – Jimbo 2010-05-26 10:06:03