zoukankan      html  css  js  c++  java
  • (转) C#异步调用使用匿名方法Lambda表达式

    委托和什么打交道最多?当然是方法。定义委托的实例需要指定方法,异步调用还需要指定回调的方法(回调函数),如果这些方法十分复杂还则罢了,可是有些时候,尤其是回调函数的内容及其简单,一句话甚至不需要回调函数,程序的逻辑也可以。为了满足委托的要求,却要反复的定义这些方法,有点烦啊…

    从.Net2.0开始,这个问题开始有了解决的办法,那就是匿名方法,看下面的例子

       1: private void button1_Click(object sender, EventArgs e)
       2: {
       3:     SampleDelegate dele = new SampleDelegate(m1);
       4:     dele.BeginInvoke(new AsyncCallback(finish), null);
       5: }
       6:  
       7: private void finish(IAsyncResult result)
       8: { 
       9:     MessageBox.Show(result.AsyncState.ToString());
       10: }

    为了进行异步调用,我定义了finish方法,虽然我什么都不需要做。匿名方法的出现,使得我有了另外一个选择。所谓匿名方法,当然就是定义一个没有名字的方法。实际上就是把原来的方法体直接写在调用的地方(当然没那么直接~),看下面的代码

       1: private void button1_Click(object sender, EventArgs e)
       2: {
       3:     SampleDelegate dele = new SampleDelegate(m1);
       4:     dele.BeginInvoke(new AsyncCallback(
       5:         delegate(IAsyncResult result) { MessageBox.Show(result.AsyncState.ToString());}
       6:         ), null);
       7: }

    我们用第5行的

       5:         delegate(IAsyncResult result) { }

    替换了原来定义的finish方法。这里的delegate告诉编译器我后面的代码是个方法,你编译的时候请自动创建它。()中是这个方法的参数,{}中的内容是这个方法的方法体。一切就这么简单,我相信你只要自己把代码敲一遍就会使用了。

    这就是匿名方法,实际上它只是让我们在写代码的时候简化了方法的定义过程。有人说匿名方法真是垃圾,它什么用都没有,它只是让我少敲了一个方法的名字而已,并且它还让我调用它的代码看上去更臃肿了。事实上似乎真的如此,但匿名方法真的这么一无是处吗?

    首先,我并不赞成你将一个复杂的方法替换成匿名方法,我认为匿名方法只适用于必须的空方法或一句话方法;

    其次,使用匿名方法你不用冥思苦想一个合适的方法名给你的方法。你不觉得写程序的时候,命名是个痛苦的事情吗?

    最后,使用匿名方法免除了你在查看一个数千行的代码的时候,为了明白方法的作用,不停的跳来跳去的麻烦。(很多时候被调用的方法很难紧挨着调用它的方法)

    到了.Net3.0(也许是3.5,记不清了),我们又有了新的选择,那就是Lambda表达式。什么是Lambda表达式?Lambda表达式代表了一个匿名方法,没错,它将一个匿名方法以表达式的方式进行书写。Lambda表达式的结构就像 ()=>{ }; 它被=>符合分成两个部分(=>读音是Goes to),左边()里面是参数列表,右边{}里面是要执行的语句,把前面的程序改成Lambda表达式:

       1: private void button1_Click(object sender, EventArgs e)
       2: {
       3:     SampleDelegate dele = new SampleDelegate(m1);
       4:     dele.BeginInvoke(new AsyncCallback(
       5:         (IAsyncResult result) => { MessageBox.Show(result.AsyncState.ToString());}
       6:         ), null);
       7: }

    你还可以做得更简单

       1: private void button1_Click(object sender, EventArgs e)
       2: {
       3:     SampleDelegate dele = new SampleDelegate(m1);
       4:     dele.BeginInvoke(new AsyncCallback(
       5:         (result) => {MessageBox.Show(result.AsyncState.ToString()); }
       6:         ), null);
       7: }

    没错,你可以忽略参数类型。编译器会自动识别参数类型的。它是如何做到的?当然是根据调用者啊,编译器查看调用者调用的委托类型的签名就可以推断出

    Lambda表达式的参数类型了。还能更简单吗?当然

       1: private void button1_Click(object sender, EventArgs e)
       2: {
       3:     SampleDelegate dele = new SampleDelegate(m1);
       4:     dele.BeginInvoke(new AsyncCallback(
       5:         r => { MessageBox.Show(r.AsyncState.ToString());}
       6:         ), null);
       7: }

    去掉括号,更改参数名称,这样的一个Lambda表达式看上去是不是比匿名方法优雅多了?或许,这就是编码的艺术了。

    从匿名方法到Lambda表达式,我们的程序本身的性能没有任何的改变,但我们的编码确变得越来越简单。如果你觉得这些都没有用,OK,你完全可以使用传统的方法去写你的代码,但对于追求艺术的人们,正是这些改变,为我们带来了幸福。

  • 相关阅读:
    模仿微信右上角菜单栏
    改变checkbox的默认样式
    webpack中的静态资源处理
    如何解决Unsupported Architecture. Your executable contains unsupported architecture '[x86_64, i386]
    页面生命周期
    关于在使用Exchange2003系统时无法向sina,yahoo,hotmail等邮箱发送邮件问题的解决方法
    重置TCP/IP协议堆栈的经历
    网通电信双线路上网,网通的走网通线路,电信的走电信线路,内网通过NAT上网,双线路故障自动切换
    在OUTLOOK或OWA中查看邮件的SCL级别(转)
    常用的RBL服务器列表及介绍
  • 原文地址:https://www.cnblogs.com/askdong/p/2172063.html
Copyright © 2011-2022 走看看