为什么以下语法有效?
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;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。