【问题标题】:Delegate with generic type only known at runtime仅在运行时知道的泛型类型的委托
【发布时间】:2017-12-08 19:14:01
【问题描述】:

在我的代码中,我声明了一个接口如下:

interface IGeneric
{
    T GetOfType<T>();
}

而且我想使用仅在运行时才知道的泛型类型调用接口的方法。这就是我目前的做法,并且有效:

Type genericArgument = ...
object interfaceImplementation = ...

MethodInfo methodInfo = typeof(IGeneric).GetMethod("GetOfType").MakeGenericMethod(genericArgument);
methodInfo.Invoke(interfaceImplementation, null);

但是因为我必须经常调用这部分代码,所以我想将方法​​信息缓存在委托中。我试过这个委托定义

private delegate T GetOfTypeDelegate<T>();

并尝试使用我检索到的方法信息创建一个委托,如上所示:

GetOfTypeDelegate<?> deleg = (GetOfTypeDelegate<?>) Delegate.CreateDelegate(typeof(GetOfTypeDelegate<?>), methodInfo);

但由于我在编译时不知道泛型参数的类型,所以我不知道在我使用 ? 的地方放置什么或如何使它工作.

非常感谢任何帮助。

【问题讨论】:

  • 这是你自己的界面吗?由于无论如何您都会以非泛型方式调用该方法,因此我会考虑重写接口以提供仅返回object 的方法的非泛型版本。由于您发现的原因,“仅在运行时知道类型”对于泛型方法确实不是一个好的用例。
  • @EdPlunkett 谢谢你,你是对的。如果没有其他办法,我将求助于重写界面。目前,我不想这样做,因为太多其他代码依赖于该通用方法。

标签: c# generics reflection delegates


【解决方案1】:

我建议使用该方法的通用和非通用版本,就像 List&lt;T&gt; 实现 IEnumerable&lt;T&gt; 同时还明确实现 System.Collections.IEnumerable

“仅在运行时知道的类型”正是泛型不打算用于的用途。你调用这个方法的方式,无论如何你只能得到object。最好有一个只返回object 的真正普通的非泛型方法。

   T GetOfType<T>();
   object GetOfType(Type t);

您甚至不必担心重载解析。诚然,实现接口的类有一些额外的负担。但正如你所见,某处会有负担。

【讨论】:

  • 我将尝试看看您的解决方案是否适合我,如果有效,我会接受这个作为答案。谢谢。
  • 这对我有用,非常感谢。此外,与我不使用委托时的性能开销相比,这个负担不算什么。谢谢。
  • @ThomasFlinkow 真棒。
猜你喜欢
  • 2021-12-19
  • 1970-01-01
  • 2019-06-01
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多