Отражение и сложные свойства - PullRequest
4 голосов
/ 31 января 2011

У меня есть объект с примитивными и сложными свойствами.

Я должен получить значения свойств по отражению.

Я использую следующие утверждения:

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

и все, но если я использую тот же код со сложным свойством, как это ...

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

propertyInfo имеет значение null, и я не могу прочитать значение «MyProp2».

Существует ли универсальный метод для этого?

Ответы [ 2 ]

7 голосов
/ 31 января 2011

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 голосов
/ 13 декабря 2011

Если вы находитесь в веб-проекте или не против ссылки на System.Web, вы можете использовать:

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

Что проще и уже было проверено Microsoft

...