6

I've got two classes.

public class Class1 {
   public string value {get;set;}
}

public class Class2 {
   public Class1 myClass1Object {get;set;}
}

I've got an object of type Class2. I need to use reflection on Class2 to set the value property... i.e, if I were doing it without reflection, this is how I would go about it:

Class2 myObject = new Class2();
myObject.myClass1Object.value = "some value";

Is there a way to do the above, while using reflection to access the property "myClass1Object.value" ?

Thanks in advance.

2
  • This is absolutely possible using standard reflection, although unless you have generic rules it seems as though this would be some one-off logic that might be better accomplished without reflection. Commented Sep 9, 2009 at 22:33
  • @Quintin I do realize that my example is a bit contrived; however, my actual situation is actually much more complex than the example I posted and does indeed reflection to accomplish. Commented Sep 9, 2009 at 22:38

3 Answers 3

14

Basically split it into two property accesses. First you get the myClass1Object property, then you set the value property on the result.

Obviously you'll need to take whatever format you've got the property name in and split it out - e.g. by dots. For example, this should do an arbitrary depth of properties:

public void SetProperty(object source, string property, object target)
{
    string[] bits = property.Split('.');
    for (int i=0; i < bits.Length - 1; i++)
    {
         PropertyInfo prop = source.GetType().GetProperty(bits[i]);
         source = prop.GetValue(source, null);
    }
    PropertyInfo propertyToSet = source.GetType()
                                       .GetProperty(bits[bits.Length-1]);
    propertyToSet.SetValue(source, target, null);
}

Admittedly you'll probably want a bit more error checking than that :)

Sign up to request clarification or add additional context in comments.

6 Comments

Very nice. I had ventured down that road already trying to get the PropertyInfo of the first Property, but I ran into a wall when I tried to call SetValue because I didn't actually have the source (i.e, you supplied the missing piece with the GetValue). Thanks!
Thanks! I had a recursive version of this. This implementation is much better: adopted!
I've tried doing something equivalent with fields of a struct (FieldInfo, Get/SetField, etc.) but didn't have any luck. Would that be expected to behave differently? For example, struct A contains struct B which contains an int i. SetProperty(source, "B.i", 4) does not change a.B.i to 4. Any thoughts?
@Ryan: At that point you'd be fetching property B, which will take a copy of it, mutating the copy, but then not assigning the copy back to B. Fundamentally, you should avoid mutable structs because they make this sort of thing painful.
@JonSkeet Thanks for your reply. That makes sense. I worked around this by throwing things (the field and source object) on a stack in the for loop and then popping and assigning on the way back out. It may not be pretty, but it works.
|
1

I was looking for answers to the case where to Get a property value, when the property name is given, but the nesting level of the property is not known.

Eg. if the input is "value" instead of providing a fully qualified property name like "myClass1Object.value".

Your answers inspired my recursive solution below:

public static object GetPropertyValue(object source, string property)
{
    PropertyInfo prop = source.GetType().GetProperty(property);
    if(prop == null)
    {
      foreach(PropertyInfo propertyMember in source.GetType().GetProperties())
      { 
         object newSource = propertyMember.GetValue(source, null);
         return GetPropertyValue(newSource, property);
      }
    }
    else
    {
       return prop.GetValue(source,null);
    }
    return null;
}

Comments

0
   public static object GetNestedPropertyValue(object source, string property)
    {
        PropertyInfo prop = null;
        string[] props = property.Split('.');

        for (int i = 0; i < props.Length; i++)
        {
            prop = source.GetType().GetProperty(props[i]);
            source = prop.GetValue(source, null);
        }
        return source;
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.