Author Topic: C# Tutorial - Using Reflection to Get Object Information  (Read 5805 times)

Offline admin

  • Administrator
  • Sr. Member
  • *****
  • Posts: 296
    • View Profile
C# Tutorial - Using Reflection to Get Object Information
« on: December 18, 2008, 08:48:38 AM »
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.

Code: [Select]
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:

Code: [Select]
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.
Code: [Select]
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:
Code: [Select]
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.