从反射创建通用Func

时间:2015-06-18 13:09:56

标签: c# reflection delegates

我在变量中指定了类型: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,并且无法更改签名。

2 个答案:

答案 0 :(得分:2)

您可以通过手动构建表达式树并将强制转换插入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的方式以传递调用该​​方法的对象。

答案 1 :(得分:0)

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

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

然后你可以用

来调用它
GetTypedInstance<SomeClass>();

而不是

GetInstance(typeof(SomeClass));