首先,稍微介绍一下。
我必须发挥作用:
static class C
{
static void F1(Type type)
{
// Do something to invoke F2<T>
}
static void F2<T>()
{
// bla bla bla
}
}
我希望调用F1(Type)
,它又应该转换到与给定类型参数相关的泛型上下文并调用泛型对应项F2<T>
。
一个简单的实现将是一个简单的反射,就像这样(为了清楚起见,我省略了绑定标志):
void F1(Type type)
{
var f2MethodInfo = typeof(C).GetMethod("F2").MakeGenericMethod(type);
f2MethodInfo.Invoke(null, new object[0]);
}
一个更高级的实现将存储 F2 的打开方法信息 -typeof(C).GetMethod("F2")
除了,但它仍然基本上是同一件事。
如果F1
被多次调用并且我们希望提高性能,那么“市场上”的标准解决方案采用字典和Delegate.CreateDelegate
方法,如下所示:
IDictionary<Type, Action> m_cache = new Dictionary<Type, Action>();
MethodInfo F2MethodInfo = typeof(C).GetMethod("F2");
void F1(Type type)
{
Action action;
if (!m_cache.TryGetValue(type, out action))
{
m_cache[type] = action = (Action)Delegate.CreateDelegate(typeof(Action), F2MethodInfo.MakeGenericMethod(type));
}
action();
}
现在回答我的问题。是否有可能完全消除字典?
例如,通过使用 Reflection.Emit 发出一些奇特的函数,该函数将接收 Type 实例和 F2MethodInfo 并在没有和字典的情况下进行内部转换?这个奇特的函数应该只发出一次并且适用于任何给定的类型。我想知道是否可以通过这种方式消除任何类型的缓存映射类型到委托。
谢谢。
编辑
为了讨论方便,让我们假设花哨的发出函数知道它应该调用 F2,这意味着它不必接收其方法信息。那么有可能放弃字典吗?