使用任意参数创建委托

时间:2010-11-14 17:26:41

标签: c# reflection parameters delegates

我有一个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表达式来实现这一点,因为它的参数类型必须在编译时才能知道。也许我需要从头开始构建一个委托?是否可以通过单独指定其主体和参数来创建委托?

谢谢

2 个答案:

答案 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约束为委托。通过对象的转换满足编译器。