2011-01-31 128 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); 

其结构简单并且已经被微软