如果在运行时类型未知,您可以在C#中使用泛型方法吗?

时间:2009-03-14 17:56:15

标签: c# generics types

解释我的意思的最简单方法是使用代码示例。这不能编译,但有没有办法实现这个效果:

foreach(Type someType in listOfTypes)
{
    SomeMethod<someType>();
}

如果可行的话会非常方便,但事实并非如此。有没有其他方法可以实现与上述相同的事情,为什么C#不允许这是一个法律声明?

编辑:似乎这样做的唯一方法是通过反射,这可能对我们的需求来说太慢了。任何关于为什么没有内置有效方法的见解以及这样的事情是否适用于C#4.0?

3 个答案:

答案 0 :(得分:23)

您可以使用反射。假设当前对象包含SomeMethod()方法,执行此操作的代码将如下所示:

GetType().GetMethod("SomeMethod").
    MakeGenericMethod(new Type[] { someType }).Invoke(this, null);

请注意,如果SomeMethod()非公开,则您的代码可能无法在较低信任的环境中执行。

答案 1 :(得分:23)

  

为什么C#不允许这是一个法律声明?

正如其他人所说,你不能这样做。为什么不?好吧,考虑你的例子:

foreach(Type someType in listOfTypes)
{
    SomeMethod<someType>();
}

请注意,在运行时之前,不能知道类型列表中的每种类型,而{em>编译时必须知道SomeMethod的类型参数。编译器不可能告诉哪个 SomeMethod<T>来解析你的调用,所以这是非法的。

在C#4中,通过将DLR包含到CLR中,可以实现这个和许多其他类似的事情。特别是,动态方法调用将使您能够调用在编译时可能不知道的方法。

答案 2 :(得分:3)

今天实现这一目标的唯一方法是通过反思。请参阅MethodInfo.MakeGenericMethod(Type[])