I want to call my generic method with a given type object.
void Foo(Type t)
{
MyGenericMethod<t>();
}
obviously doesn't work.
How can I make it work?
I want to call my generic method with a given type object.
void Foo(Type t)
{
MyGenericMethod<t>();
}
obviously doesn't work.
How can I make it work?
This approach will not work. The reason why is that Type is an object who's type is determined at runtime. However you are trying to use it to call a generic method. A generic method call's type is established at compile time. Hence a Type object can't ever be used for a type parameter on a generic method.
You need to use reflection, unfortunately (for the reasons Jared mentioned). For example:
MethodInfo method = typeof(Foo).GetMethod("MyGenericMethod");
method = method.MakeGenericMethod(t);
method.Invoke(this, new object[0]);
Obviously you'd want more error checking in reality :)
Side note: my local MSDN doesn't specify that the parameter from MakeGenericMethod is a parameter array, so I'd have expected to require:
method = method.MakeGenericMethod(new Type[] { t });
but it seems it is a parameter array in reality, and the online MSDN docs agree. Odd.
Your code sample won't work, because the generic method expects a type identifier, not a an instance of the Type class. You'll have to use reflection to do it:
public class Example {
public void CallingTest()
{
MethodInfo method = typeof (Example).GetMethod("Test");
MethodInfo genericMethod = method.MakeGenericMethod(typeof (string));
genericMethod.Invoke(this, null);
}
public void Test<T>()
{
Console.WriteLine(typeof (T).Name);
}
}
Do keep in mind that this is very brittle, I'd rather suggest finding another pattern to call your method.
Another hacky solution (maybe someone can make it a bit cleaner) would be to use some expression magic:
public class Example {
public void CallingTest()
{
MethodInfo method = GetMethod<Example>(x => x.Test<object>());
MethodInfo genericMethod = method.MakeGenericMethod(typeof (string));
genericMethod.Invoke(this, null);
}
public static MethodInfo GetMethod<T>(Expression<Action<T>> expr)
{
return ((MethodCallExpression) expr.Body)
.Method
.GetGenericMethodDefinition();
}
public void Test<T>()
{
Console.WriteLine(typeof (T).Name);
}
}
Note passing the 'object' type identifier as a generic type argument in the lambda. Couldn't figure out so quickly how to get around that. Either way, this is compile-time safe I think. It just feels wrong somehow :/