简体   繁体   中英

.net get Properties using Reflection at Multilevel

Sorry if this is a duplicate. I searched and was not able to find an answer. How do I use reflection to get Values of Properties of class at multilevel?

I have a List of string that has some string values like this:

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

I have two classes

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

I used reflection and I am able to get the values of firstname, lastname and phone. But how do I get the values in the location class? It throws an Error. I change the List to just have Location / City . I am missing something. I dont want to do Multiple for loops as the level might drill down to n level. (4 max to be realistic)

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

You'd have to get the Location instance first:

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

If you're using a version before 4.5 you'll probably need to send in one additional parameter to the GetValue method - it can be , null both times because the properties aren't indexers.

Here are two methods I wrote to solve this issue

This one gets a queue of properties from a base object:

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

And this one uses the queue and the object to get the actual 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;
}

Probably wouldn't hurt to add some error checking and such as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM