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.
First, let's create a simple object that contains some fields,
properties, and events. I'll be using this object throughout the rest of
the tutorial.
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);
To get a list of public fields in an object, we'll use Type's
GetFields
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 customattributes
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.
Comments
Post a Comment