【问题标题】:Create generic Func from reflection从反射创建通用 Func
【发布时间】:2015-06-18 13:09:55
【问题描述】:

我在变量中指定了类型:Type hiddenType。我需要创建一个Func<T> 委托,其中T 是上述变量中​​指定的类型并分配一个方法:

var funcType = typeof(Func<>).MakeGenericType(hiddenType);
Func<object> funcImplementation = () => GetInstance(hiddenType);

var myFunc= Delegate.CreateDelegate(funcType , valueGenerator.Method);

它不起作用 - 因为 funcImplementation 返回 object 而不是期望的。在运行时,它肯定是hiddenType 中指定的类型的实例。

GetInstance 返回object,并且无法更改签名。

【问题讨论】:

  • 我看不到您想要实现的目标。由于GetInstance 根据声明仅返回object,因此Func&lt;object&gt; 在这里绝对可以。
  • @HimBromBeere OP 希望 myFunc 成为 Func&lt;HiddenType&gt;,而不是 Func&lt;object&gt;。他尝试使用CreateDelegate,但没有成功。

标签: c# reflection delegates


【解决方案1】:

您可以通过手动构建表达式树并将转换插入hiddenType 来解决此问题。构造表达式树时允许这样做。

var typeConst = Expression.Constant(hiddenType);
MethodInfo getInst = ... // <<== Use reflection here to get GetInstance info
var callGetInst = Expression.Call(getInst, typeConst);
var cast = Expression.Convert(callGetInst, hiddenType);
var del = Expression.Lambda(cast).Compile();

注意:上面的代码假定GetInstancestatic。如果它不是静态的,请更改构造callGetInst 的方式以传递调用该​​方法的对象。

【讨论】:

  • 但是,生成的委托不是强类型的,我认为这是 OP 真正想要的。
  • @HimBromBeere 这个委托将是强类型的,因为它的类型将与typeof(Func&lt;&gt;).MakeGenericType(hiddenType) 兼容。当然它不会是静态类型的委托(这是不可能的,因为类型是隐藏的)。
  • 谢谢!有一阵子我以为Expression 可以做到,但我不知道怎么吃那块蛋糕。
【解决方案2】:

如果您无法更改 GetInstance 签名,您可以考虑使用通用包装器,而不是使用类型:

private Func<THidden> GetTypedInstance<THidden>()
{
    return () => (THidden)GetInstance(typeof(THidden));
}

然后你可以用它来调用它

GetTypedInstance<SomeClass>();

而不是

GetInstance(typeof(SomeClass));

【讨论】:

  • 我认为问题在于 hiddenType 仅在运行时已知,因此静态绑定到通用包装器将不起作用。
猜你喜欢
  • 2022-12-07
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
  • 1970-01-01
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多