使用反射在多级中获取.NET属性

4

如果这是一个重复的问题,我很抱歉。我搜索了一下,但没有找到答案。 如何使用反射在多级别上获取类的属性值?

我有一个字符串列表,其中包含一些字符串值,例如:

ClassNames =  {"FirstName", "LastName", "Location.City", "Location.State", "Location.Country", "PhoneNo"}

我有两个类

public class Details
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Location Location { get; set; }
        public string PhoneNo { get; set; }
    }

public class Location
    {
        public long City { get; set; }
        public string State { get; set; }
        public string Country { get; set; }
    }

我利用反射机制成功获取了firstname、lastname和phone的值。但是如何获取location类中的值呢?出现了错误。我将列表更改为只包含Location / City。可能是我遗漏了某些内容。我不希望使用多个循环,因为级别可能会一直钻下去(最多4级)。

foreach (string fieldname in ClassNames)
 {
 string fieldvalue = RestultDTO[indexValue]GetType().GetProperty(fieldname) ;
 }
2个回答

1
您需要先获取 Location 实例:
var s = "Location.City";
var sVals = s.Split('.');

// here [t] is the TypeInfo of [Details]
var l = t.GetProperty(sVals[0]);
        ^ gets the Location PropertyInfo (really only need to do this once

var val = l.GetProperty(sVals[1]).GetValue(l.GetValue(o));
          ^ gets the PropertyInfo for the property you're after (City in this case)
                                  ^ gets the actual value of that property
                                           ^ gets the value of Location for o where o is an instance of Details

如果您使用的是版本4.5之前,则可能需要向GetValue方法发送一个额外的参数-两次都可以是null,因为属性不是索引器。


谢谢!我正在尝试类似的东西,我能够得到输出。我的唯一挑战是当我需要进入下一个级别时。比如说,在这里,如果我想要城市名称和城市代码,那么我将不得不再次执行相同的过程。有没有办法循环遍历并获取,而不是手动拆分它们并在每个级别上执行操作? - Night Monger

0
这里是我写来解决这个问题的两种方法:
第一种方法从基础对象中获取属性队列:
private static Queue<PropertyInfo> GetProperty(object obj, string path)
{
    Queue<PropertyInfo> values = new Queue<PropertyInfo>();

    Type object_type = obj.GetType();

    string[] properties = path.Split('.');

    PropertyInfo propertyInfo = null;

    foreach (string property in properties)
    {
        if (propertyInfo != null)
        {
            Type propertyType = propertyInfo.PropertyType;
            propertyInfo = propertyType.GetProperty(property);
            values.Enqueue(propertyInfo);
        }
        else
        {
            propertyInfo = object_type.GetProperty(property);
            values.Enqueue(propertyInfo);
        }
    }

    return values;
}

这个例子使用队列和对象来获取实际值:

private static T GetValue<T>(object obj, Queue<PropertyInfo> values)
{
    object location = obj;

    while (values.Count > 0)
    {
        location = values.Dequeue().GetValue(location);
    }

    return (T)location;
}

最好也加上一些错误检查之类的东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接