Getting Nested Object Property Value Using Reflection

前端 未结 11 2007
甜味超标
甜味超标 2020-12-03 06:55

I have the following two classes:

public class Address
{
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public         


        
相关标签:
11条回答
  • 2020-12-03 07:29

    Yet another variation to throw out there. Short & sweet, supports arbitrarily deep properties, handles null values and invalid properties:

    public static object GetPropertyVal(this object obj, string name) {
        if (obj == null)
            return null;
    
        var parts = name.Split(new[] { '.' }, 2);
        var prop = obj.GetType().GetProperty(parts[0]);
        if (prop == null)
            throw new ArgumentException($"{parts[0]} is not a property of {obj.GetType().FullName}.");
    
        var val = prop.GetValue(obj);
        return (parts.Length == 1) ? val : val.GetPropertyVal(parts[1]);
    }
    
    0 讨论(0)
  • 2020-12-03 07:31

    I use this method to get the values from properties (unlimited number of nested property) as below:

    "Property"

    "Address.Street"

    "Address.Country.Name"

        public static object GetPropertyValue(object src, string propName)
        {
            if (src == null) throw new ArgumentException("Value cannot be null.", "src");
            if (propName == null) throw new ArgumentException("Value cannot be null.", "propName");
    
            if(propName.Contains("."))//complex type nested
            {
                var temp = propName.Split(new char[] { '.' }, 2);
                return GetPropertyValue(GetPropertyValue(src, temp[0]), temp[1]);
            }
            else
            {
                var prop = src.GetType().GetProperty(propName);
                return prop != null ? prop.GetValue(src, null) : null;
            }
        }
    

    Here the Fiddle: https://dotnetfiddle.net/PvKRH0

    0 讨论(0)
  • 2020-12-03 07:32

    This will work for unlimited number of nested property.

    public object GetPropertyValue(object obj, string propertyName)
    {
        var _propertyNames = propertyName.Split('.');
    
        for (var i = 0; i < _propertyNames.Length; i++)
        {
            if (obj != null)
            {
                var _propertyInfo = obj.GetType().GetProperty(_propertyNames[i]);
                if (_propertyInfo != null)
                    obj = _propertyInfo.GetValue(obj);
                else
                    obj = null;
            }
        }
    
        return obj;
    }
    

    Usage:

    GetPropertyValue(_employee, "Firstname");
    GetPropertyValue(_employee, "Address.State");
    GetPropertyValue(_employee, "Address.Country.Name");
    
    0 讨论(0)
  • 2020-12-03 07:32

    I made an extension method on type for this propose:

    public static class TypeExtensions
    {
        public static PropertyInfo GetSubProperty(this Type type, string treeProperty, object givenValue)
        {
            var properties = treeProperty.Split('.');
            var value = givenValue;
    
            foreach (var property in properties.Take(properties.Length - 1))
            {
                value = value.GetType().GetProperty(property).GetValue(value);
    
                if (value == null)
                {
                    return null;
                }
            }
    
            return value.GetType().GetProperty(properties[properties.Length - 1]);
        }
    
        public static object GetSubPropertyValue(this Type type, string treeProperty, object givenValue)
        {
            var properties = treeProperty.Split('.');
            return properties.Aggregate(givenValue, (current, property) => current.GetType().GetProperty(property).GetValue(current));
        }
    }
    
    0 讨论(0)
  • 2020-12-03 07:35
    var address = GetPropertyValue(GetPropertyValue(emp1, "Address"), "AddressLine1");
    

    Object Employee doesn't have a single property named "Address.AddressLine1", it has a property named "Address", which itself has a property named "AddressLine1".

    0 讨论(0)
  • 2020-12-03 07:37
    public object GetPropertyValue(object obj, string propertyName)
    {
        foreach (var prop in propertyName.Split('.').Select(s => obj.GetType().GetProperty(s)))
           obj = prop.GetValue(obj, null);
    
        return obj;
    }
    

    Thanks, I came here looking for an answer to the same problem. I ended up modifying your original method to support nested properties. This should be more robust than having to do nested method calls which could end up being cumbersome for more than 2 nested levels.

    0 讨论(0)
提交回复
热议问题