2011-01-31 8 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がnullで、私ができます"MyProp2"の値を読み取っていません。

これを行う一般的な方法がありますか?

答えて

7

MyProp1.MyProp2はベースオブジェクトのプロパティではなく、MyProp1は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) 

あなたは

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

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

使用状況をテストするために、そして、この拡張メソッドのようなもの(ごめんその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); 

    } 

を試みることができます

+0

右によってテストされていますが、Iオブジェクトのプロパティ値を直接読み取るためには、このメカニズムを一般化する必要があります。可能だ? –

+0

できます! ...私は同じロジックでメソッドを書いたことがありますが、あなたのバージョンはよりエレガントです。ありがとう! –

+0

問題ありません:-) –

0

あなたがWebプロジェクトにしている、またはのSystem.Webを参照する気にしない場合は、あなたが使用できます。

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

簡単で、すでにマイクロソフト