让我试着举个例子。
class Session (
public delegate string CleanBody();
public static void Execute(string name, string q, CleanBody body) ...
可以像:
一样使用Session.Execute("foo", "bar", delegate() { string x="beep"; /* whatever*/ return x; });
但是如果我需要运行的是通过MethodInfo.Invoke - 就像在不同的dll中没有任何类型的依赖关系。像:
Type type = Type.GetType("Bla.Session, FooSessionDll", true);
MethodInfo methodInfo = type.GetMethod("Execute");
Object [] args = { "foo", "bar", delegate() // Doesn't compile, now that ?
{
string x="beep"; /* whatever*/ return x;
}
methodInfo.Invoke("Trial Execution :-)", args);
无论应用什么技巧/演员,它都必须是这样的,它仍然作为真正的代表到达Execute。实际代表可能有更复杂的签名等等。
答案 0 :(得分:0)
private static class Invoker
{
private static string Method()
{
return "beep";
}
public static object Invoke()
{
Type type = Type.GetType("Bla.Session, FooSessionDll", true);
MethodInfo methodInfo = type.GetMethod("Execute");
Type delegateType = methodInfo.GetParameters()[2].ParameterType;
Delegate delegateInstance = Delegate.CreateDelegate(delegateType, typeof(Invoker).GetMethod("Method"));
object[] args = new object[] { "foo", "bar", delegateInstance };
return methodInfo.Invoke(null, args);
}
}
答案 1 :(得分:0)
好的,找到了解决方案:Func<<TResult>>
,以及整个Func模板系列。就我发布的示例而言,将Execute(...)的签名转换为:
public static void Execute(string name, string q, Func<string> body)
在功能上等同于具有显式命名委托的那个,即任何对其具有类型依赖性的代码仍然可以使用
Session.Execute("foo", "bar", delegate() { ... });
代码更改为零,任何独立的dll现在都可以执行:
Func<string> d = delegate() { .....}
并将其作为正常参数传递给Object[]
。
还有另一个帖子问“Func<>
有什么好处” - 这就是: - )
它允许打破依赖关系和不合理的绑定,对使用它的现有代码进行零代码更改。一个条件是现有代码使用匿名方法(如示例中)而不是旧式显式委托创建。