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

Posted

技术标签:

【中文标题】如果类型在运行时之前未知,您可以在 C# 中使用泛型方法吗?【英文标题】:Can you use generics methods in C# if the type is unknown until runtime? 【发布时间】:2009-03-14 17:56:15 【问题描述】:

解释我的意思的最简单方法是使用代码示例。这个不编译,但是有什么办法可以达到这个效果:

foreach(Type someType in listOfTypes)

    SomeMethod<someType>();

如果可以的话会很方便,但事实并非如此。是否有其他方法可以实现与上述相同的目标,为什么 C# 不允许将其作为法律声明?

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

【问题讨论】:

不太清楚你想在这里实现什么。您能否提供更多上下文和/或对 SomeMethod 需要做什么的解释(以及为什么需要为类型列表执行此操作)? 是的,您可以像其他人提到的那样通过反射来做到这一点,但请记住,反射非常缓慢。如果在您的情况下性能很重要,请考虑其他方法。 我需要索引我们对象数据库中的所有类型,而不用担心何时添加或删除新类型等 我明白了。如果您只想索引类型,为什么不将 System.Type 对象传递给方法? 好吧,如果我是你,我只会将类型作为常规参数传递。最后,泛型类型参数几乎就像参数一样,但是您必须使用反射才能在您的情况下设置它们,因此请考虑使用“Type”类型的普通参数 【参考方案1】:

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

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

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

【讨论】:

【参考方案2】:

为什么 C# 不允许将其作为法律声明?

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

foreach(Type someType in listOfTypes)

    SomeMethod<someType>();

请注意,类型列表中的每个类型直到运行时 才能知道,而SomeMethod 的类型参数必须在编译时 知道。编译器不可能告诉哪个 SomeMethod&lt;T&gt; 来解析你的调用,所以这是非法的。

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

【讨论】:

别担心,没有难过的感觉! *** 充满了不被接受的好答案。你选择了最能表达你意思的那个——我只是为好奇的人添加了一些额外的信息。 ;) 既然 C# 4 已经发布,您可以使用 dynamic 的示例更新您的答案 使用动态的例子是:SomeMethod((dynamic)someType); @nightcoder 如果 SomeMethod 有一个 someType 参数,这很好用,但是如果没有像示例中那样的其他参数怎么办?【参考方案3】:

今天唯一能做到这一点的方法是通过反思。见MethodInfo.MakeGenericMethod(Type[])。

【讨论】:

以上是关于如果类型在运行时之前未知,您可以在 C# 中使用泛型方法吗?的主要内容,如果未能解决你的问题,请参考以下文章

你可以在 C# 中使用泛型表单吗?

你可以在 C# 中使用泛型表单吗?

第五章 泛型

使用 Lambda 表达式调用通用方法(以及仅在运行时知道的类型)

为什么要使用泛型?怎么用泛型?

C#中的泛型是啥意思?