我有一个System.Reflection.MethodInfo,并希望有一个方法可以创建一个代表该方法的委托(最好是一个Func< ...>或一个Action< ...>)给定一个实例调用它。
理想情况下,我想要类似下面的伪代码:
public TDelegate GetMethod<TDelegate>(MethodInfo methodToRepresent, object instanceToInvokeOn)
{
return (TDelegate)((parameters....) => methodToRepresent.Invoke(instanceToInvokeOn, all parameters in an object[]));
}
其中TDelegate表示所表示方法的签名。如果签名不匹配,则应抛出异常。
我意识到我可能无法使用简单的lambda表达式来实现这一点,因为它的参数类型必须在编译时才能知道。也许我需要从头开始构建一个委托?是否可以通过单独指定其主体和参数来创建委托?
谢谢
答案 0 :(得分:3)
我真的不明白你的问题。但也许你想要这个:
public TDelegate GetMethod<TDelegate>(MethodInfo methodToRepresent, object instanceToInvokeOn)
where TDelegate:class
{
return (TDelegate)(object)Delegate.CreateDelegate(typeof(TDelegate), instanceToInvokeOn, methodToRepresent);
}
答案 1 :(得分:2)
您可以使用以下方法执行此操作。请注意,使用此方法无法真正创建泛型Action<...>
,因为正如您所说,这些类型在编译时是未知的。但这会让你非常接近。
public delegate void DynamicInvokeDelegate(params object[] args);
public static DynamicInvokeDelegate CreateDynamicInvokeDelegate(MethodInfo method, object instance) {
return args => method.Invoke(instance, args);
}
如果您需要委托来返回值:
public delegate object DynamicInvokeWithReturnDelegate(params object[] args);
public static DynamicInvokeWithReturnDelegate CreateDynamicInvokeWithReturnDelegate(MethodInfo method, object instance) {
return args => method.Invoke(instance, args);
}
修改强>
实际上看起来你可能想要这段代码:
public static T GetDelegate<T>(MethodInfo method, object instance)
where T : class
{
return (T)(object)Delegate.CreateDelegate(typeof(T), instance, method);
}
需要(object)
强制转换,因为编译器不允许您将Delegate
强制转换为任意随机类型,并且您不能将T
约束为委托。通过对象的转换满足编译器。