【发布时间】:2016-02-11 12:22:01
【问题描述】:
我正在尝试创建一个方法,该方法返回给定类型的委托,其主体运行函数中指定的某些代码。即
public Delegate GenerateDelegate(Type delegateType)
{
// create a delegate of type 'Type'
// specify the code of this delegate
// return the delegate object
}
如果我事先知道类型,或者至少知道参数和返回类型,我显然可以只返回该类型的委托,一个匿名委托,使用我想要的任何代码。但是,问题是我希望它适用于几乎任何类型的非泛型委托,并且我希望能够利用委托类型所具有的参数,并返回正确的类型。
我查看了使用 ILGenerator.Emit() 或 CodeDOM 来实现此目的的不同选项。但是,我可能想在返回的委托中做一些相当复杂的事情,并且希望能够直接在 C# 中编写代码,因为我不确定是否可以使用 IL 或 CodeDOM 来实现这一点。作为一个伪解决方案,就像 Delegate.DynamicInvoke(params object[]) 可以采用匿名参数一样,我想我希望能够做这样的事情。
public Delegate GenerateDelegate(Type delegateType)
{
return Delegate.CreateDelegate(delegateType, GetType().GetMethod("RunEvent"));
}
public static object RunEvent(params object[] parameters)
{
// some specified code, depending on contents of parameters
return null;
}
RunEvent() 可以将任意数量的参数作为对象数组,并返回对象。遗憾的是,这不起作用并引发以下异常:
无法绑定到目标方法,因为它的签名或安全透明度与委托类型的不兼容。
不知何故,我认为对象数组参数应该与委托可能具有的任何参数组合兼容,但作为对象的返回类型可能会返回一些与给定 delegateType 不兼容的对象,或者如果 delegateType 返回 void。这可能会导致一些问题。
对于我自己的使用,我在运行时知道所有参数和返回类型,并且可以检查这一点以确保一切安全。有什么办法可以让我这样工作吗?
【问题讨论】:
-
“对象数组参数应该与委托可能具有的任何参数组合兼容” – 并非如此。它们不匹配
ref/out参数,它们不匹配值类型参数(当您正常调用此类方法时未应用隐式装箱)。对要调用的方法一无所知似乎是一种非常错误的方法。 -
你是对的。我没有考虑 ref/out 参数。支持该功能也很好,但对于我目前的使用,我不需要 ref/out 使用,如果这会以任何方式简化解决方案。