如果类型在运行时之前未知,您可以在 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<T>
来解析你的调用,所以这是非法的。
在 C# 4 中,通过将 DLR 包含到 CLR 中,这和许多其他类似的事情将成为可能。特别是,动态方法调用将使您能够调用在编译时可能不知道的方法。
【讨论】:
别担心,没有难过的感觉! *** 充满了不被接受的好答案。你选择了最能表达你意思的那个——我只是为好奇的人添加了一些额外的信息。 ;) 既然 C# 4 已经发布,您可以使用dynamic
的示例更新您的答案
使用动态的例子是:SomeMethod((dynamic)someType);
@nightcoder 如果 SomeMethod 有一个 someType 参数,这很好用,但是如果没有像示例中那样的其他参数怎么办?【参考方案3】:
今天唯一能做到这一点的方法是通过反思。见MethodInfo.MakeGenericMethod(Type[])。
【讨论】:
以上是关于如果类型在运行时之前未知,您可以在 C# 中使用泛型方法吗?的主要内容,如果未能解决你的问题,请参考以下文章