我只明白,如果我愿意,变体 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
但您可能希望调用一个方法,其中 - 比方说 - 事件中没有参数(带有object
和EventArgs
参数)。在这种情况下,您有一些选择:
- 使用适当的原型创建一个事件处理程序方法,然后简单地调用您想要的方法。
- 创建一个匿名委托(就像您所做的那样或使用 lambda)。不要忘记匿名委托不能简单地与事件处理程序分离......