C# .net使用多级反射获取属性

C# .net使用多级反射获取属性,c#,.net,reflection,C#,.net,Reflection,对不起,如果这是重复的。我搜索了一下,没有找到答案。 我如何使用反射在多级上获取类的属性值 我有一个字符串列表,其中包含如下字符串值: ClassNames = {"FirstName", "LastName", "Location.City", "Location.State", "Location.Country", "PhoneNo"} 我有两节课 public class Details { public string FirstName { get; set

对不起,如果这是重复的。我搜索了一下,没有找到答案。 我如何使用反射在多级上获取类的属性值

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

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类中的值呢?它抛出了一个错误。我将列表更改为只包含位置/城市。我错过了一些东西。我不想做多个for循环,因为级别可能会向下钻取到n个级别。(最多4个是现实的)


您必须首先获取
位置
实例:

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
,因为属性不是索引器。

以下是我为解决此问题编写的两个方法

这一个从基本对象获取属性队列:

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静态队列GetProperty(对象obj,字符串路径)
{
队列值=新队列();
Type object_Type=obj.GetType();
string[]properties=path.Split('.');
PropertyInfo PropertyInfo=null;
foreach(属性中的字符串属性)
{
if(propertyInfo!=null)
{
类型propertyType=propertyInfo.propertyType;
propertyInfo=propertyType.GetProperty(属性);
值。排队(propertyInfo);
}
其他的
{
propertyInfo=对象类型.GetProperty(属性);
值。排队(propertyInfo);
}
}
返回值;
}
这一个使用队列和对象来获取实际值:

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;
}
private static T GetValue(对象对象,队列值)
{
对象位置=obj;
而(values.Count>0)
{
location=values.Dequeue().GetValue(位置);
}
返回(T)位置;
}

添加一些错误检查等可能不会有什么坏处。

谢谢!!我尝试了一些类似的东西,我能够得到输出。我唯一的挑战是当我必须进入下一个阶段时。就像这里,如果我想要City.Name和City.Code,那么我必须再次执行相同的过程。有没有什么方法可以在我不手动拆分它们并在每个级别执行的情况下循环并获取它们?
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;
}