Question

Is there a way to obtain the object behind a property by reflection?

I am trying to manage a dynamic setting of a property.

Example:

class Animal
{
  public string Name {get;set;}
  public string Family {get;set;}
}

class Zoo
{
 public Animal Lion {get;set;}
 public Animal Panda {get;set;}
}


class Test
{
   public void SetLionNameWithReflection()
  {

    Zoo londonZoo = new Zoo();
    Type zooType = typeof(Zoo);
    PropertyInfo lionProperty = zooType.GetProperty("Lion");

    // Now what to write here so that I can manage to set Lion's name to Kaspar?
    // (to manage this by reflection Lion.Name = "Kaspar");

  }

}

What lines should I add more at the commented part above?

Thanks!

Was it helpful?

Solution

I don't think you actually need to know the object behind a property. Use the SetValue method to set its value to "Kaspar":

EDIT - as per dlev's comment, this is how it should look like:

Lion kaspar = new Lion { Name="Kaspar" };
zooType.SetValue(londonZoo, kaspar, null);

OTHER TIPS

A property doesn't necessarily have an object "behind" it.

It's defined by 2 functions, get and set, that can do whatever you want, and not necessarily return an object's value at all.

What you used is just a syntactic sugar to make it easier to make a property to wrap a member.

No you can't use reflection to definitively get the object behind an arbitrary property. Largely because it's not guaranteed that every property is bound to an object. It could just as easily be a calculated value.

public class Student {
  public string m_firstName;
  public string m_lastName;

  public string FullName {
    get { return String.Format("{0} {1}", m_firstName, m_lastName); }
  }
}

In this case the property FullName produces a calculated value and has no single backing object.

The case you're listing though is for auto-properties. There is likely a way to dig through the fields and use a form of name matching to get the one backing a given auto-property. However such a solution would be fragile to versioning and certainly not recomended.

Can you add an overloaded constructor to your animal object, which will allow you to pass in the animal name, like this?:

londonZoo.GetProperty("Lion").SetValue(londonZoo, new Lion("Kaspar"), null); 

First you need to create the lion:

var lion = Activator.CreateInstance(lionProperty.PropertyType);

Then you need to set the Lion property of the zoo:

lionProperty.SetValue(londonZoo, lion, null);

Then you can get the Name property of the lion:

PropertyInfo property = lion.GetType().GetProperty("Name", 
    BindingFlags.Public | BindingFlags.Instance);

Then you can set its name:

if (property != null && property.CanWrite)
{
    property.SetValue(lion, "Kaspar", null);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top