Sunday, September 02, 2007

Reflection on Generic, Part 3 - Instantiate Generic Type

In this post, we will look at how to use reflection to instantiate a generic type.
First, let start with an example of how to do it in the usual way without reflection.

static void Main(string[] args)
{
List<string> list = InstatiateList();
list.ForEach(delegate(string s) { Console.WriteLine(s); });
Console.ReadLine();
}

private static List<string> InstatiateList()
{
List<string> listOfString = new List<string>();
listOfString.Add("AAA");
listOfString.Add("BBB");
return listOfString;
}
The above code will print out
AAA
BBB

Now, lets do it the reflection way.
static void Main(string[] args)    
{
List<string> list = InstatiateListReflectionWay();
list.ForEach(delegate(string s) { Console.WriteLine(s); });
Console.ReadLine();
}
 
private static List<string> InstatiateListReflectionWay()
{
// Get the metadata for List_Of_T
Type t = typeof(List<>);
 
// Make a type definition for List_Of_String
Type[] typeArg = new Type[1] { typeof(string) };
Type listOfStringDef = t.MakeGenericType(typeArg);
 
// Get the method metadata for Add() method.
MethodInfo mi = listOfStringDef.GetMethod("Add");
 
// Create an instance of List_Of_String.
object listOfString = Activator.CreateInstance(listOfStringDef);
 
// Add two element to the list.
mi.Invoke(listOfString, new object[] { "CCC" });
mi.Invoke(listOfString, new object[] { "DDD" });
return (List<string>)listOfString;
}

The above code will print out:
CCC
DDD

Even when you use reflection, the runtime still give you strongly type checking protection against your code. To prove this, insert the following code before the return statement in InstatiateListReflectionWay().
mi.Invoke(listOfString, new object[] { 123 });

This time, when you run the code again, you will see an exception thrown.
Exception thrown.
Exception thrown when insert a number into list_of_string. Click to view in full size.

Labels: , ,

0 Comments:

Post a Comment

<< Home