2

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

1:

textBox1.Invoke(new MethodInvoker(b));

2:

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

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

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

但是版本 2 到底是什么?这里的“代表”关键字是什么意思/是什么?

4

2 回答 2

2

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

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

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

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

在第二个版本中,有一个额外的委托被调用(它的主体只是调用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)。不要忘记匿名委托不能简单地与事件处理程序分离......
于 2014-04-22T12:13:25.480 回答
-2

V1 创建一个新MethodInvoker对象并将您的b方法作为参数传递给它。MethodInvoker然后“与 b 一起做”的是类本身。

在 V2 中,您创建一个匿名方法并将其强制转换为MethodInvoker并且不实例化任何“附加对象”,并且您的委托是“直接”执行的。使用 Lambda 调用它的另一种更短的方法:

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

在 V1 中,您还可以替换MethodInvoker为您自己的实现,例如 aTryCatchLogInvokerb直接执行,而是将其包装以记录“内部b”发生的异常。

于 2014-04-22T12:11:53.393 回答