Invoking Generic Methods With Reflection
Invoking Generic Methods With Reflection
A few days ago
I answered a question
in the ASP.NET forums
concerning the issue
of invoking generic methods
with reflection.
In this post I’m going to explain that issue. If generics or reflection are new to you
you can read about them in the next MSDN links:
Getting started
You will need to create a new console application in order to make the example work.
In the following examples I’m going to use the following class:
public class MyClass
{
#region Methods
#region Regular Method
public string GetHelloString(string name)
{
return string.Format("Hello {0}", name);
}
#endregion
#region Generic Methods
public string GetString<M>(M item)
{
return string.Format("The item you sent is: {0}",
item.ToString());
}
public List<M> GetList<M>(params M[] items)
{
return items.ToList<M>();
}
#endregion
#endregion
}
The class holds one non generic method, GetHelloString, and two generic
methods - GetString that returns a string and GetString that returns a List of
generic type.
Invoking Methods With Reflection
The first step to learn is how to invoke a regular method with reflection.
In order to invoke a method with reflection you need to do the following
things:
- Get the type of the class that you want to invoke it’s method.
- Get the MethodInfo by the GetMethod method of Type.
- Invoke the method on the class with the relevant parameters.
The following code will do the trick:
Type t = typeof(MyClass);
MethodInfo mi = t.GetMethod("GetHelloString");
MyClass c = new MyClass();
object obj = mi.Invoke(c, new object[] { "Scott" });
Console.WriteLine(obj.ToString());
Console.ReadLine();
These lines of code will write to the console “Hello Scott”.
There are more ways to invoke methods with reflection but for the simplicity
of the example I use this method.
Invoking Generic Methods With reflection
After we saw how to invoke a regular method lets discuss the difference with
generic methods. Generic methods are as their name indicate generic. That
means that they get some type as a parameter which dictate the type to work
with inside the method. The reflection mechanism in the .Net framework helps
us to “inject” the type to the MethodInfo and to construct a generic
MethodInfo to be invoke. We use the MakeGenericMethod method of
MethodInfo in order to “inject” the type or types to the method.
The following method can show you a way to use the MakeGenericMethod
method:
// build the generic method with the relevant type
private static MethodInfo InjectTypeToGenericMethod<T>(string methodName)
{
// get the type and the method
Type t = typeof(MyClass);
MethodInfo mi = t.GetMethod(methodName);
// make the generic method with the type
Type[] argTypes = { typeof(T) };
MethodInfo result = mi.MakeGenericMethod(argTypes);
return result;
}
The example shows how to “inject” one type to the generic method.
You can do the “injection” with multiple types as well.
The other things to do in order to invoke the generic method are the same
as in regular methods case.
So, in order to invoke a generic method we need to do the following things:
- Get the type of the class that you want to invoke it’s method.
- Get the MethodInfo by the GetMethod method of Type.
- Build a set of type arguments to the generic method.
- Inject the type arguments to the generic method using the
MakeGenericMethod. - Invoke the method on the class with the relevant parameters.
The following code will give you the example I wrote from the start:
class Program
{
static void Main(string[] args)
{
#region Regular Method Invokation
Type t = typeof(MyClass);
MethodInfo mi = t.GetMethod("GetHelloString");
MyClass c = new MyClass();
object obj = mi.Invoke(c, new object[] { "Scott" });
Console.WriteLine(obj.ToString());
Console.ReadLine();
#endregion
#region Generic Methods Invokation
// build the generic method with the relevant type
MethodInfo miWithType = InjectTypeToGenericMethod<int>(
"GetString");
// invoke the generic method on a set of arguments
Object result = miWithType.Invoke(new MyClass(),
new object[] { 1 });
// write to output the result
Console.WriteLine(result);
Console.ReadLine();
// build the generic method with the relevant type
miWithType = InjectTypeToGenericMethod<string>(
"GetList");
// invoke the generic method on a set of arguments
string[] parameters = { "first", "second" };
result = miWithType.Invoke(new MyClass(),
new Object[] { parameters });
List<string> list = (List<string>)result;
// write to output the result
foreach (var item in list)
{
Console.WriteLine(item);
}
Console.ReadLine();
#endregion
}
// build the generic method with the relevant type
private static MethodInfo InjectTypeToGenericMethod<T>(
string methodName)
{
// get the type and the method
Type t = typeof(MyClass);
MethodInfo mi = t.GetMethod(methodName);
// make the generic method with the type
Type[] argTypes = { typeof(T) };
MethodInfo result = mi.MakeGenericMethod(argTypes);
return result;
}
}
Summary
Lets sum up the post, I showed how to invoke a generic methods with
reflection. The only difference between invoking a regular method and
invoking a generic one is the “injection” of the type (or types) to the
method to be invoked. If you want to get more information in area of
generics and reflection you can read the following links: