MethodInvoker的这两种用法之间的区别

时间:2014-04-22 12:07:24

标签: c# delegates method-invocation

MethodInvoker的两种用法之间究竟有什么区别:

1:

textBox1.Invoke(new MethodInvoker(b));

2:

textBox1.Invoke((MethodInvoker)delegate { b(); });

我只明白,如果我愿意,那个变种2允许我用参数调用b()。 但这两个版本有什么区别?

版本1对我来说很清楚: 我创建一个新的委托并将其传递给我的b()方法,该方法具有与MethodInvoker委托相同的返回类型和参数。代表的标准例。

但是版本2到底是什么? “委托”关键字的含义是什么?

2 个答案:

答案 0 :(得分:2)

  

我只明白,如果我愿意,那个变种2允许我用参数调用b()。

不,即使是第一个版本,您也可以这样做:

textBox1.Invoke(new MethodInvoker(b), parameter1, parameter2);
  

但这2个版本有什么区别?

在第二个版本中,有一个额外的委托被调用(它的主体只是调用b())。可能有用例(例如,如果你需要一个闭包,见后面),但在这种情况下它没有任何意义。

  

但是版本2到底是什么? “委托”关键字的含义是什么?

这是一个匿名方法,如果你检查生成的代码,你会发现它与某种程度上相同:

void MyAnonymousMethod() {
    b();
}

void b() {
}

...

textBox1.Invoke(new MethodInvoker(MyAnonymousMethod));

正如你所看到的那样,它是无用的(在这种情况下),因为你添加了一个无用的扩展委托调用。如果您使用它来捕获变量,它可能会很有用:

int a = CalculateValueA();
textBox1.Invoke((MethodInvoker)delegate {
    b(a / CalculateValueC(), anotherParameter); 
});

请注意,这与此非常不同:

int a = CalculateValueA();
textBox1.Invoke(new MethodInvoker(b), a / CalculateValueC());

由于何时函数将被调用并且表达式被评估。要了解所有含义,请参阅MSDN以获取有关C#中的闭包的详细信息。手写的相同代码编写起来要复杂得多(您需要定义类来保存参数/函数调用)。对反编译代码的快速检查将使这一点更加清晰。

另一种常见情况是,您必须适应 e方法原型。 MethodInvoker不是这种情况,但您可能想要调用一个方法 - 比方说 - 没有来自事件的参数(带有objectEventArgs参数)。在这种情况下,您有一些选择:

  • 使用适当的原型创建一个事件处理程序方法,然后只需调用所需的方法。
  • 创建一个匿名委托(就像你做的那样或使用lambda)。不要忘记匿名委托不能简单地从事件处理程序中分离出来......

答案 1 :(得分:-2)

V1创建一个新的MethodInvoker对象,并将b方法作为参数传递给它。 MethodInvoker然后"对b"做什么是班级本身。

在V2中,您创建一个匿名方法并将其强制转换为MethodInvoker,并且不会实现任何"其他对象"并且你的代表直接执行了#34;使用Lambdas调用它的另一种更短的方法是:

textBox1.Invoke(() => b()); // or .Invoke((Action)() => b());

在V1中,您还可以使用自己的实现替换MethodInvoker,例如一个TryCatchLogInvoker,它不直接执行b,而是将其包装起来记录发生的异常"在b"内。