MethodInvoker的两种用法之间究竟有什么区别:
1:
textBox1.Invoke(new MethodInvoker(b));
2:
textBox1.Invoke((MethodInvoker)delegate { b(); });
我只明白,如果我愿意,那个变种2允许我用参数调用b()。 但这两个版本有什么区别?
版本1对我来说很清楚: 我创建一个新的委托并将其传递给我的b()方法,该方法具有与MethodInvoker委托相同的返回类型和参数。代表的标准例。
但是版本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
不是这种情况,但您可能想要调用一个方法 - 比方说 - 没有来自事件的参数(带有object
和EventArgs
参数)。在这种情况下,您有一些选择:
答案 1 :(得分:-2)
V1创建一个新的MethodInvoker
对象,并将b
方法作为参数传递给它。 MethodInvoker
然后"对b"做什么是班级本身。
在V2中,您创建一个匿名方法并将其强制转换为MethodInvoker
,并且不会实现任何"其他对象"并且你的代表直接执行了#34;使用Lambdas调用它的另一种更短的方法是:
textBox1.Invoke(() => b()); // or .Invoke((Action)() => b());
在V1中,您还可以使用自己的实现替换MethodInvoker
,例如一个TryCatchLogInvoker
,它不直接执行b
,而是将其包装起来记录发生的异常"在b
"内。