C# Tutorial - Using Reflection to Get Object Information
Every once in a while you might want to know what fields, properties, or events a certain type of object contains at runtime. A common use for this information is serialization. .NET contains lots of different serialization techniques, like binary and XML, but sometimes you just have to roll your own. This tutorial is going to demonstrate how to get a list of public fields, properties, and events from objects at runtime.
public class MyObject
{
//public fields
public string myStringField;
public int myIntField;
public MyObject myObjectField;
//public properties
public string MyStringProperty { get; set; }
public int MyIntProperty { get; set; }
public MyObject MyObjectProperty { get; set; }
//public events
public event EventHandler MyEvent1;
public event EventHandler MyEvent2;
}
The .NET class that gives us access to all of this is the Type class. To get a Type object, we simply use the typeof keyword:
Type myObjectType = typeof(MyObject);
//you can use
// Type myObjectType = MyObjectInstance.GetType();
// as MyObjectInstance is an Instance of MyObject
To get a list of public fields in an object, we'll use Type's GetField method:
Type myObjectType = typeof(MyObject);
System.Reflection.FieldInfo[] fieldInfo =
myObjectType.GetFields();
foreach (System.Reflection.FieldInfo info in fieldInfo)
Console.WriteLine(info.Name);
// Output:
// myStringField
// myIntField
// myObjectField
An important thing to note here is that the fields are not guaranteed to come out in any particular order. If you use GetFields, you should never depend on the order being consistent. The FieldInfo class that gets returned actually contains a lot of useful information. It also contains the ability to set that field on an instance of MyObject - that's where the real power comes in.
MyObject myObjectInstance = new MyObject();
foreach (System.Reflection.FieldInfo info in fieldInfo)
{
switch (info.Name)
{
case "myStringField":
info.SetValue(myObjectInstance, "string value");
break;
case "myIntField":
info.SetValue(myObjectInstance, 42);
break;
case "myObjectField":
info.SetValue(myObjectInstance, myObjectInstance);
break;
}
}
//read back the field information
foreach (System.Reflection.FieldInfo info in fieldInfo)
{
Console.WriteLine(info.Name + ": " +
info.GetValue(myObjectInstance).ToString());
}
// Output:
// myStringField: string value
// myIntField: 42
// myObjectField: MyObject
Combining this ability with the ability to create custom attributes provides a framework on which almost any serialization technique can be built.
Properties and events are retrieved almost identically to fields:
Type myObjectType = typeof(MyObject);
//Get public properties
System.Reflection.PropertyInfo[] propertyInfo =
myObjectType.GetProperties();
foreach (System.Reflection.PropertyInfo info in propertyInfo)
Console.WriteLine(info.Name);
// Output:
// MyStringProperty
// MyIntProperty
// MyObjectProperty
//Get events
System.Reflection.EventInfo[] eventInfo =
myObjectType.GetEvents();
foreach (System.Reflection.EventInfo info in eventInfo)
Console.WriteLine(info.Name);
// Output:
// MyEvent1
// MyEvent2
The PropertyInfo class is very similar to the FieldInfo class and also contains the ability to set the value of the property on an instance. It also gives you the ability to individually receive the get and set accessors as MethodInfo classes through the GetAccessors method.
An EventInfo object gives you lots of information about the event and the ability to add events to instances of MyObject.
I think that about does it. Hopefully this helps anyone out there wanting to get information about objects at runtime. If something didn't make sense, or you've got other questions, just post your comments.