匿名方法相信很多人都听过,它是C#2.0的一个新特性,顾名思义,匿名方法就是没有名称的方法。那么在C#中的匿名方法有哪些好处,在C#中如何使用呢?
匿名方法最明显的好处就是可以降低另写一个方法的工作量,另外一个好处就是可以访问调用者的变量,降低传参数的复杂度,下面就通过一些使用例子来具体看看。
1、在事件中使用匿名方法
下面是一个定时器的小例子,我们常规的写法如下:

常规写法
    class EventTest
    {
        public void Test()
        {
            System.Timers.Timer timersTimer = new System.Timers.Timer();

            timersTimer.Enabled = true;
            timersTimer.Interval = 5000;
            timersTimer.Elapsed += new System.Timers.ElapsedEventHandler(timersTimer_Elapsed);
            Console.ReadLine();
        }

        void timersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Console.WriteLine(System.DateTime.Now);
        }
    }

对于事件的处理我们需要单独写一个方法timersTimer_Elapsed,那么如果使用匿名方法,就可以省掉这个方法的定义,如下所示:

    class EventTest
    {
        public void Test()
        {
            System.Timers.Timer timersTimer = new System.Timers.Timer();

            timersTimer.Enabled = true;
            timersTimer.Interval = 5000;
            timersTimer.Elapsed +=
                delegate(object sender, System.Timers.ElapsedEventArgs e)
                {
                    Console.WriteLine(System.DateTime.Now);
                };
            Console.ReadLine();
        }
    }

也就是把方法的实现直接写在内部。

2、在我们自己的代理中使用匿名方法
比如如下一个字符串转化的例子,按照传统的方法来写的话,对于每一种转化规则都需要单独定义一个方法:

常规写法
    class DelegateTest
    {
        delegate string Convert(string text);

        public void Test()
        {
            string strText = "123451234512345";

            Test2(ConvertA, strText);
            Test2(ConvertB, strText);
            Test2(ConvertC, strText);

            Console.ReadLine();
        }

        private void Test2(Convert convert, string strText)
        {
            Console.WriteLine(convert(strText));
        }

        public string ConvertA(string strText)
        {
            return strText.Replace("1", "A");
        }
        public string ConvertB(string strText)
        {
            return strText.Replace("1", "B");
        }
        public string ConvertC(string strText)
        {
            return strText.Replace("1", "C");
        }
    }

我们的例子中有三种规则,那么就要定义三个方法,如果使用匿名方法的话,代码就会很简单:

    class DelegateTest
    {
        delegate string Convert(string text);

        public void Test()
        {
            string strText = "123451234512345";

            Test2(delegate(string strText2)
                {
                    return strText2.Replace("1", "A");
                }, strText);
            Test2(delegate(string strText2)
                {
                    return strText2.Replace("1", "B");
                }, strText);
            Test2(delegate(string strText2)
                {
                    return strText2.Replace("1", "C");
                }, strText);

            Console.ReadLine();
        }

        private void Test2(Convert convert, string strText)
        {
            Console.WriteLine(convert(strText));
        }
    }

3、优化例子2,不再传递参数
在例子2中我们是把参数传到你们方法内部的,其实在匿名方法内部可以直接取得当前调用者的变量,节省了传递参数的代码量:

    class AnonTest
    {
        delegate string Convert();

        public void Test()
        {
            string strText = "123451234512345";

            Test2(delegate()
                {
                    return strText.Replace("1", "A");
                });
            Test2(delegate()
                {
                    return strText.Replace("1", "B");
                });
            Test2(delegate()
                {
                    return strText.Replace("1", "C");
                });

            Console.ReadLine();
        }

        private void Test2(Convert convert)
        {
            Console.WriteLine(convert());
        }
    }

这样一来,代码是不是看起来很整洁:)

当然代码虽然看起来很少,实际上编译器在编译时还是会生成其他方法的。也就是说匿名方法可以减少代码量,节省开发时间,但是对于性能方法没有什么提升的。
我们通过IL DASM工具可以查看一下AnonTest类编译后的代码,会发现增加一个新类,在这个类里面生成了三个方法和一个同名的strText变量:

然后在Test方法中会调用这些新生成的方法,Test如下所示:

.method public hidebysig instance void  Test() cil managed
{
  // 代码大小       83 (0x53)
  .maxstack  4
  .locals init ([0] class AnonMethod.AnonTest/'<>c__DisplayClass3' '<>8__locals4')
  IL_0000:  newobj     instance void AnonMethod.AnonTest/'<>c__DisplayClass3'::.ctor()
  IL_0005:  stloc.0
  IL_0006:  nop
  IL_0007:  ldloc.0
  IL_0008:  ldstr      "123451234512345"
  IL_000d:  stfld      string AnonMethod.AnonTest/'<>c__DisplayClass3'::strText
  IL_0012:  ldarg.0
  IL_0013:  ldloc.0
  IL_0014:  ldftn      instance string AnonMethod.AnonTest/'<>c__DisplayClass3'::'<Test>b__0'()
  IL_001a:  newobj     instance void AnonMethod.AnonTest/Convert::.ctor(object,
                                                                        native int)
  IL_001f:  call       instance void AnonMethod.AnonTest::Test2(class AnonMethod.AnonTest/Convert)
  IL_0024:  nop
  IL_0025:  ldarg.0
  IL_0026:  ldloc.0
  IL_0027:  ldftn      instance string AnonMethod.AnonTest/'<>c__DisplayClass3'::'<Test>b__1'()
  IL_002d:  newobj     instance void AnonMethod.AnonTest/Convert::.ctor(object,
                                                                        native int)
  IL_0032:  call       instance void AnonMethod.AnonTest::Test2(class AnonMethod.AnonTest/Convert)
  IL_0037:  nop
  IL_0038:  ldarg.0
  IL_0039:  ldloc.0
  IL_003a:  ldftn      instance string AnonMethod.AnonTest/'<>c__DisplayClass3'::'<Test>b__2'()
  IL_0040:  newobj     instance void AnonMethod.AnonTest/Convert::.ctor(object,
                                                                        native int)
  IL_0045:  call       instance void AnonMethod.AnonTest::Test2(class AnonMethod.AnonTest/Convert)
  IL_004a:  nop
  IL_004b:  call       string [mscorlib]System.Console::ReadLine()
  IL_0050:  pop
  IL_0051:  nop
  IL_0052:  ret
} // end of method AnonTest::Test

C#强化系列文章四:匿名方法的使用相关推荐

  1. C# 强化系列文章四:匿名方法的使用

    C#强化系列文章四:匿名方法的使用 匿名方法 相信很多人都听过,它是C#2.0的一个新特性,顾名思义,匿名方法就是没有名称的方法.那么在C#中的匿名方法有哪些好处,在C#中如何使用呢? 匿名方法最明显 ...

  2. Spring Boot 2.0系列文章(四):Spring Boot 2.0 源码阅读环境搭建

    前提 前几天面试的时候,被问过 Spring Boot 的自动配置源码怎么实现的,没看过源码的我只能投降��了. 这不,赶紧来补补了,所以才有了这篇文章的出现,Spring Boot 2. 0 源码阅 ...

  3. cnn系列文章四 --池化层和简单卷积网络示例

    cnn系列文章三 --padding和strides详解 一句歌词继续中: <霜雪千年> 苔绿青石板街 斑驳了流水般岁月 小酌三盏两杯 理不清缠绕的情结 典型的卷积神经网络 convolu ...

  4. iPhone开发系列文章(四)-开发iPhone应用程序(一)

    本人翻译的Apple Dev Center的技术资料并稍作修改. 转载请注明出处:http://blog.csdn.net/zhyzh2046/ 从较高的层面看,开发iPhone应用的过程与开发Mac ...

  5. C#强化系列文章三:实验分析C#中三种计时器使用异同点

    C#中提供了三种类型的计时器: 1.基于 Windows 的标准计时器(System.Windows.Forms.Timer) 2.基于服务器的计时器(System.Timers.Timer) 3.线 ...

  6. C#强化系列文章五:动态代码的使用(反射和动态生成类)

    在软件开发尤其是框架和底层开发时,为了更灵活的控制代码,常常需要进行一些动态的操作.比如根据用户的输入等动态的调用类中的方法或者根据数据库表结构.用户要求动态的生成一些类,然后再动态的调用类中的方法. ...

  7. DJYGUI系列文章四:GK文本显示

    目录 1 GK文本显示概述 1.1 ansi系 1.2 unicode系 1.3 DJYGUI文本显示 2 字符集说明 3 字符集API说明 3.1 ModuleInstall_Charset:字符编 ...

  8. 【微信小程序开发•系列文章一】入门

    本系统文章主要有以下几篇: <[微信小程序开发•系列文章一]入门> <[微信小程序开发•系列文章二]视图层> <[微信小程序开发•系列文章三]数据层> <[微 ...

  9. 云原生存储系列文章(一):云原生应用的基石

    作者| 郡宝 阿里云技术专家 参与文末留言互动,即有机会获得赠书福利! 导读:存储服务支撑了应用的状态.数据的持久化,是计算机系统中的重要组成部分,也是所有应用得以运行的基础,其重要性不言而喻.在存储 ...

最新文章

  1. python之xlrd、xlwt学习
  2. 字符串 mysql索引,长字符串的MySQL索引
  3. CSS hack:针对IE6,IE7,IE8,IE9,firefox显示不同效果
  4. hfs快速搭建HTTP文件服务器
  5. 我的Java后端书架
  6. 中小企业的软件需求问题
  7. LeetCode 790. 多米诺和托米诺平铺(动态规划)
  8. Linux系统编程17:进程控制之进程等待为什么进程需要被等待wait方法和waitpid方法阻塞和非阻塞等待
  9. 深度学习行人重识别ReID最新综述与展望
  10. 无心剑随感《程序人生乐无穷》
  11. 【iOS开发】使用XCode 10添加Launch Image(启动图片)
  12. 时序数据库技术体系-时序数据存储模型设计
  13. 生活随笔:你会狗眼看人低吗?
  14. linux libxml2 rpm安装,Linux系统libxml2安装过程
  15. Kinect:少年你步履蹒跚是不是没睡好
  16. 撤回的微信消息腾讯服务器有记录吗,教你如何查看对方已经撤回的微信消息
  17. php微信支付mch_id参数格式错误,再说一下微信支付踩到的坑 mch_id 参数格式错误...
  18. 蓝牙资讯|苹果 AirPods Pro 2正式发布,有惊喜也有遗憾
  19. for await of使用
  20. msys2在windows10系统的安装

热门文章

  1. 【性能优化之道】每秒上万并发下的Spring Cloud参数优化实战
  2. 原创 人物志|山东省临沭县 - 一位身残志坚的奋斗青年 - 吴忠军
  3. STC12C5A60S2 内部AD+1602显示
  4. Linux中crontab定时执行python程序
  5. Word 2003文件保存和另存为操作是否熟练掌握的有关测试
  6. linux nfs共享文件
  7. Serial Communications in Win32
  8. saas的计费数据库设计_如何构建和扩展SaaS计费解决方案
  9. 精确哈克,以贪婪为基础的欺诈式引流法
  10. zabbix简介及基本安装(一)