c# – 使用BackgroundWorker的Lambda
为什么以下语法有效?
BackgroundWorker bw = new BackgroundWorker(); String one = resultFromSomeMethod(); String two = resultFromOtherMethod(); String three = resultFromThirdMethod(); bw.DoWork += (a,b) => TestMethod(one,two,three); 其中TestMethod定义为: private void TestMethod(String one,String two,String three){ //Do Stuff!! } DoWorkEventHandler被定义为一个委托,它接受两个参数:object sender和EventArgs e.但是,上面的TestMethod没有这样的参数.通过我对委托的理解,要创建一个新的委托,该方法必须符合委托的声明.我似乎通过使用lambda绕过了这个限制.上面的语法如何以及为什么工作,即使我尝试创建一个新的DoWorkEventHandler(TestMethod),它肯定不会工作? 我在Lambda Expressions上阅读了Eric White的blog,但它似乎没有回答这个问题. 解决方法
让我为你澄清一下lambda:
(a,b) => TestMethod("","",""); 翻译为: private void AnonymousLambda(object a,EventArgs b) { TestMethod("",""); } lambda的语法是: implicit method arguments => method body 隐式方法参数由方法分配给(或调用)的预期签名确定.因为您将此lambda表达式分配给DoWorkEventHandler委托,所以它会自动将a和b分别解释为对象和EventArgs. 在某些情况下,编译器无法推断lambda参数的隐式类型,因此您也可以明确地编写它们: (object a,EventArgs b) => TestMethod("",""); 所以你真的在你匿名创建的另一种方法体内调用你的TestMethod!而outer方法具有DoWorkEventHandler方法签名. 编辑 根据有关字符串变量的其他问题详细信息,编译器将在代码上创建一个闭包,以将变量包含在方法范围内.代码基本上成为一个新类,它将变量保存为私有字段,然后在调用中引用它们: public class AnonymousClosureClass { public void AnonymousLambda(object a,EventArgs b) { // Note the reference to the original class instance String one = originalClassReference.one; String two = originalClassReference.two; String three = originalClassReference.three; TestMethod(one,three); } } 您的主要代码实际上变为: BackgroundWorker bw = new BackgroundWorker(); // Note: these may become field members to remain visible to the closure class String one = resultFromSomeMethod(); String two = resultFromOtherMethod(); String three = resultFromThirdMethod(); var closure = new AnonymousClosureClass(); bw.DoWork += closure.AnonymousLambda; 最后,值得注意的是,这根本不是实际生成的闭包代码的命名或外观. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |