加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用BackgroundWorker的Lambda

发布时间:2020-12-15 20:47:47 所属栏目:百科 来源:网络整理
导读:为什么以下语法有效? BackgroundWorker bw = new BackgroundWorker();String one = resultFromSomeMethod();String two = resultFromOtherMethod();String three = resultFromThirdMethod();bw.DoWork += (a,b) = TestMethod(one,two,three); 其中TestMetho
为什么以下语法有效?

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;

最后,值得注意的是,这根本不是实际生成的闭包代码的命名或外观.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读