Dynamically setting object properties (Reflection)

  • Thread starter Thread starter chris fellows
  • Start date Start date
C

chris fellows

In VS2005 (C#) I want to set the properties of an object dynamically at
runtime from an XML configuration file but without having to know the
property name when writing the code. The properties are user-defined classes
so I need to be able to iterate through the properties of each sub-object
and set the property accordingly.

For example, Instead of having to write the code
MyObject.SubObjectOne.MyStringProperty = "Some text" I will configure it
like this <Property Name="MyObject.SubObjectOne.MyStringProperty"
Value="Some text"/>.

Can someone help me out as to how to do this? I can iterate thru' the
properties of MyObject (using PropertyInfo) but can't see how to iterate
thru' the properties of each sub-object or even how to set the property
value.
 
Check PropertyInfo.GetValue and SetValue methods.

GetValue will provide you with sub-object, which you can interate just like
you iterate main object. Note binding flags - most probably you will need
Instance flag and for private properties NonPublic.

HTH
Alex
 
First - I'd advocate PropertyDescriptor over PropertyInfo so that you
can support "views" rather than just "models"; if you are doing a lot
of this, I can also show you a way to use PropertyDescriptors to
vastly accelerate the access (reflection is otherwise slow).

Here you go though:

using System;
using System.Windows.Forms;
using System.ComponentModel;
static class Program {
static void Main() {
MyClass1 c1 = new MyClass1();
c1.Nested = new MyClass1();

object obj = c1, value = "NewValue";
string expr = "Nested.InnerItem.Value";

string[] sections = expr.Split('.');
int lastIndex = sections.Length - 1;
// walk to the penultimate property through successive
properties
for (int i = 0; i < lastIndex; i++) {
obj =
TypeDescriptor.GetProperties(obj)[sections].GetValue(obj);
}
// set the last property
TypeDescriptor.GetProperties(obj)[sections[lastIndex]].SetValue(obj,
value);

// test it
string newVal = c1.Nested.InnerItem.Value;

}

}
class MyClass1 {
private readonly MyClass2 inner = new MyClass2();
private MyClass1 nested;
public MyClass1 Nested {
get { return nested; }
set { nested = value; }
}
public MyClass2 InnerItem {
get { return inner; }
}
}
class MyClass2 {
private string value;
public string Value {
get { return value; }
set { this.value = value; }
}
}
 
Back
Top