Retrieving Type information using Reflection

July 3rd, 2008 by ganton | Print

There are many situations when we need to retrieve part of the information of a type. It can be done via Reflection. This sample uses it to retrieve type’s attributes, fields, properties, methods and constructors. It also sets values to properties and fields and invoke the two custom methods of the class. Fisrst of all we will create a custom class named MyClass and a custom attribute named CustomAttribute (code snippet below).

[sourcecode language="csharp"] 
[Custom(Value = "Some Value")]
 public class MyClass
 {
  private string MyPrivateField;
  public string MyPublicField;
  private string MyPrivateProperty { get; set; }
  public string MyPublicProperty { get; set; }
  public MyClass()
  {
  }
  public MyClass(string value)
  {
  }
  private string MyPrivateMethod(string parameter)
  {
   return parameter;
  }
  private string MyPublicMethod(string parameter)
  {
   return parameter;
  }
 }
 public class CustomAttribute : Attribute
 {
  public string Value { get; set; }
 }
[/sourcecode]

Having MyClass we are ready to explore it using Reflection. For this purpose we will create a
console application. The code of its main method is placed in the snippet below. An instance of MyClass is created using Activator in the beginning (line 6). Then Type information about attributes, fields, properties, methods and constructors is retrieved (line 7 - 16). Having this information we can display on the console part of the information per each type of members (line 17  - 59). At the end of this method properties’ and fields’ values are changed (line 70 - 77) and methods which are not constructors and property methods and have one parameter of type string are executed (line 79 - 92).

[sourcecode language="csharp"]  
static void Main(string[] args)
  {
   Type type = typeof(MyClass);
   // creating myClass instance using reflection
   MyClass myClass = (MyClass) Activator.CreateInstance(type);
   // retrieve custom attributes used to decorate our object
   object[] attributes = type.GetCustomAttributes(false);
   // retrieve all fields (public and non public)
   FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
   // retrieve all properties (public and non public)
   PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
   // retrieve all methods (public and non public)
   MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
   // retrieve all constructors
   ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
   foreach (var item in attributes)
   {
    CustomAttribute attribute = item as CustomAttribute;
    if (attribute != null)
    {
     Console.WriteLine(string.Format(”CustomAttriute’s Value = {0}”, attribute.Value));     
    }
   }
   Console.WriteLine();
   foreach (var item in fields)
   {
    Console.WriteLine(string.Format(”Field name = {0}; type = {1}; access level = {2}”,
     item.Name, item.FieldType, item.IsPublic == true ? “Public” : item.IsPrivate ? “Private” : “Unknown”));
   }
   Console.WriteLine();
   foreach (var item in properties)
   {
    Console.WriteLine(string.Format(”Property name = {0}; type = {1}; read = {2}, write = {3}”,
     item.Name, item.PropertyType, item.CanRead, item.CanWrite));
   }
   Console.WriteLine();
   foreach (var item in methods)
   {
    if (!item.IsConstructor)
    {
     Console.WriteLine(string.Format(”Method name = {0}; return type = {1}; access level = {2}”,
      item.Name, item.ReturnType, item.IsPublic == true ? “Public” : item.IsPrivate ? “Private” : item.IsVirtual ? “Virtual” : “Unknown”));
     foreach (var prm in item.GetParameters())
     {
      Console.WriteLine(string.Format(”Parameter name = {0}, type = {1}”, prm.Name, prm.ParameterType));
     }
    }    
   }
   Console.WriteLine();
   foreach (var item in constructors)
   {
    Console.WriteLine(string.Format(”Ctor name = {0}; is constructor = {1}; access level = {2}”,
     item.Name, item.IsConstructor, item.IsPublic == true ? “Public” : item.IsPrivate ? “Private” : item.IsVirtual ? “Virtual” : “Unknown”));
    foreach (var prm in item.GetParameters())
    {
     Console.WriteLine(string.Format(”Parameter name = {0}, type = {1}”, prm.Name, prm.ParameterType));
    }    
   }
   // set values to fields or properties
   foreach (var item in fields)
   {
    item.SetValue(myClass, item.Name);
   }
   foreach (var item in properties)
   {
    item.SetValue(myClass, item.Name, null);
   }
   // it is not a problem to retrieve values from fields and properties
   foreach (var item in fields)
   {
    Console.WriteLine(string.Format(”Field name = {0}, value = {1}”, item.Name, item.GetValue(myClass)));    
   }
   foreach (var item in properties)
   {
    Console.WriteLine(string.Format(”Property name = {0}, value = {1}”, item.Name, item.GetValue(myClass, null)));
   }
   // invoke methods
   Type stringType = typeof(string);
   ParameterInfo info;
   string set = “set_”;
   string get = “get_”;
   foreach (var item in methods)
   {
    if (!item.IsConstructor && (!item.Name.StartsWith(set) || !item.Name.StartsWith(set)))
    {
     ParameterInfo[] parameters = item.GetParameters();
     if (parameters.Length == 1 && (info = parameters[0]).ParameterType == stringType)
     {
      object returnValue = item.Invoke(myClass, new object[] { “value” });
      // returnValue == “value”      
     }
    }
   }
  }
[/sourcecode]

Here’s the output of the application.

Leave a Reply