2011-01-31 130 views
4

我有一個具有原始和複雜屬性的對象。反射和複雜屬性

我必須通過反射來獲取屬性值。

我用這個語句:

Dim propertyInfo As PropertyInfo = MYITEM.GetType().GetProperty("MyProp1") 
Dim propertyValue As Object = propertyInfo.GetValue(MYITEM, Nothing) 

和it'ok,但如果我用這樣的複雜屬性相同的代碼...

Dim propertyInfo As PropertyInfo = MYITEM.GetType().GetProperty("MyProp1.MyProp2") 
Dim propertyValue As Object = propertyInfo.GetValue(MYITEM, Nothing) 

中的PropertyInfo是零,我可以沒有讀到「MyProp2」的價值。

存在一個通用的方法來做到這一點?

回答

7

MyProp1.MyProp2不是您的基礎對象的屬性,MyProp1是該屬性,那麼MyProp2是MyProp1返回的對象的屬性。

試試這個:

Dim propertyInfo1 As PropertyInfo = MYITEM.GetType().GetProperty("MyProp1") 
Dim propertyValue1 As Object = propertyInfo.GetValue(MYITEM, Nothing) 

Dim propertyInfo2 As PropertyInfo = propertyValue1.GetType().GetProperty("MyProp2") 
Dim propertyValue2 As Object = propertyInfo2.GetValue(propertyValue1, Nothing) 

你可以嘗試這樣的事情擴展方法(對不起它在C#)

public static TRet GetPropertyValue<TRet>(this object obj, string propertyPathName) 
    { 
     if (obj == null) 
     { 
      throw new ArgumentNullException("obj"); 
     } 

     string[] parts = propertyPathName.Split('.'); 
     string path = propertyPathName; 
     object root = obj; 

     if (parts.Length > 1) 
     { 
      path = parts[parts.Length - 1]; 
      parts = parts.TakeWhile((p, i) => i < parts.Length-1).ToArray(); 
      string path2 = String.Join(".", parts); 
      root = obj.GetPropertyValue<object>(path2); 
     } 

     var sourceType = root.GetType(); 
     return (TRet)sourceType.GetProperty(path).GetValue(root, null); 

    } 

然後測試

public class Test1 
{ 
    public Test1() 
    { 
     this.Prop1 = new Test2(); 
    } 
    public Test2 Prop1 { get; set; } 
} 


public class Test2 
{ 
    public Test2() 
    { 
     this.Prop2 = new Test3(); 
    } 
    public Test3 Prop2 { get; set; } 
} 

public class Test3 
{ 
    public Test3() 
    { 
     this.Prop3 = DateTime.Now.AddDays(-1); // Yesterday 
    } 
    public DateTime Prop3 { get; set; } 
} 

使用

Test1 obj = new Test1(); 
var yesterday = obj.GetPropertyValue<DateTime>("Prop1.Prop2.Prop3"); 
+0

右測試,但我必須推廣這種機制,以直接讀取對象屬性值。有可能嗎? – 2011-01-31 10:10:45

0

如果你在一個web項目,或不介意引用的System.Web,你可以使用:

object resolvedValue = DataBinder.Eval(object o, string propertyPath); 

其結構簡單並且已經被微軟