Getting Nested Object Property Value Using Reflection

37,799

Solution 1

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".

Solution 2

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.

Solution 3

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");

Solution 4

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

Solution 5

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]);
}
Share:
37,799

Related videos on Youtube

Kumar
Author by

Kumar

Updated on July 09, 2022

Comments

  • Kumar
    Kumar almost 2 years

    I have the following two classes:

    public class Address
    {
        public string AddressLine1 { get; set; }
        public string AddressLine2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Zip { get; set; }
    }
    
    public class Employee
    {
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
        public Address EmployeeAddress { get; set; }
    }
    

    I have an instance of the employee class as follows:

        var emp1Address = new Address();
        emp1Address.AddressLine1 = "Microsoft Corporation";
        emp1Address.AddressLine2 = "One Microsoft Way";
        emp1Address.City = "Redmond";
        emp1Address.State = "WA";
        emp1Address.Zip = "98052-6399";
    
        var emp1 = new Employee();
        emp1.FirstName = "Bill";
        emp1.LastName = "Gates";
        emp1.EmployeeAddress = emp1Address;
    

    I have a method which gets the property value based on the property name as follows:

    public object GetPropertyValue(object obj ,string propertyName)
    {
        var objType = obj.GetType();
        var prop = objType.GetProperty(propertyName);
    
        return prop.GetValue(obj, null);
    }
    

    The above method works fine for calls like GetPropertyValue(emp1, "FirstName") but if I try GetPropertyValue(emp1, "Address.AddressLine1") it throws an exception because objType.GetProperty(propertyName); is not able to locate the nested object property value. Is there a way to fix this?

  • Andrew Barber
    Andrew Barber over 11 years
    Is this a response to the other answer?
  • YeenFei
    YeenFei about 6 years
    how can it works when the same "obj" is used for reflection type retrieving?
  • Noob
    Noob over 3 years
    @YeenFei he updates the obj value in the foreach (see below the for each code part...)