cod*_*nix 53 .net c# generics reflection types
我想用给定的类型对象调用我的泛型方法.
void Foo(Type t)
{
MyGenericMethod<t>();
}
Run Code Online (Sandbox Code Playgroud)
显然不起作用.
我怎样才能使它工作?
Eri*_*kel 56
您的代码示例将不起作用,因为泛型方法需要类型标识符,而不是Type类的实例.你必须使用反射来做到这一点:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
请记住,这是非常脆弱的,我宁愿建议找另一种模式来调用你的方法.
另一个hacky解决方案(可能有人可以使它更清洁)将使用一些表达魔术:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
注意将'object'类型标识符作为lambda中的泛型类型参数传递.无法弄清楚如何快速解决这个问题.无论哪种方式,我认为这是编译时安全的.以某种方式感觉不对:/
Jon*_*eet 18
不幸的是,你需要使用反射(由于Jared提到的原因).例如:
MethodInfo method = typeof(Foo).GetMethod("MyGenericMethod");
method = method.MakeGenericMethod(t);
method.Invoke(this, new object[0]);
Run Code Online (Sandbox Code Playgroud)
显然你想在现实中更多的错误检查:)
旁注:我的本地MSDN没有指定MakeGenericMethod中的参数是参数数组,所以我原本应该要求:
method = method.MakeGenericMethod(new Type[] { t });
Run Code Online (Sandbox Code Playgroud)
但它似乎是现实中的参数数组,在线MSDN文档同意.奇.