Reflection and Complex Properties

I have an object with primitive and complex properties.

I need to get property values ​​by reflection.

I use the following statements:

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

and it'ok, but if I use the same code with a complex property like this ...

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

propertyInfo value is null and I cannot read the value "MyProp2".

Is there a universal method for this?

+4
source share
2 answers

MyProp1.MyProp2 is not a property of your base object, MyProp1 is a property that MyProp2 is a property of the object returned by MyProp1.

Try the following:

 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) 

You can try something like this extension method (sorry in 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); } 

Then to check

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

Using

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

If you are in a web project or do not mind linking to System.Web, you can use:

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

Which is easier and has already been verified by Microsoft

0
source

Source: https://habr.com/ru/post/1337746/


All Articles