从反射创建通用 Func
Create generic Func from reflection
我在变量中指定了类型:Type hiddenType
。我需要创建一个 Func<T>
委托,其中 T
是上述变量中指定的类型并分配一个方法:
var funcType = typeof(Func<>).MakeGenericType(hiddenType);
Func<object> funcImplementation = () => GetInstance(hiddenType);
var myFunc= Delegate.CreateDelegate(funcType , valueGenerator.Method);
它不起作用 - 因为 funcImplementation
是 returns object
而不是所需的。在运行时,它肯定是 hiddenType
.
中指定类型的实例
GetInstance
returns object
无法更改签名。
您可以通过手动构建表达式树并将强制转换插入 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();
注:以上代码假设GetInstance
为static
。如果不是静态的,改变你构造的方式callGetInst
传递调用方法的对象。
如果您无法更改 GetInstance 签名,则可以考虑使用通用包装器而不是使用类型:
private Func<THidden> GetTypedInstance<THidden>()
{
return () => (THidden)GetInstance(typeof(THidden));
}
然后你可以用
调用它
GetTypedInstance<SomeClass>();
而不是
GetInstance(typeof(SomeClass));
我在变量中指定了类型:Type hiddenType
。我需要创建一个 Func<T>
委托,其中 T
是上述变量中指定的类型并分配一个方法:
var funcType = typeof(Func<>).MakeGenericType(hiddenType);
Func<object> funcImplementation = () => GetInstance(hiddenType);
var myFunc= Delegate.CreateDelegate(funcType , valueGenerator.Method);
它不起作用 - 因为 funcImplementation
是 returns object
而不是所需的。在运行时,它肯定是 hiddenType
.
GetInstance
returns object
无法更改签名。
您可以通过手动构建表达式树并将强制转换插入 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();
注:以上代码假设GetInstance
为static
。如果不是静态的,改变你构造的方式callGetInst
传递调用方法的对象。
如果您无法更改 GetInstance 签名,则可以考虑使用通用包装器而不是使用类型:
private Func<THidden> GetTypedInstance<THidden>()
{
return () => (THidden)GetInstance(typeof(THidden));
}
然后你可以用
调用它GetTypedInstance<SomeClass>();
而不是
GetInstance(typeof(SomeClass));