专栏首页GreenLeavesC# lambda表达式

C# lambda表达式

学了N多久的委托,终于告一段落,现在可以开始lambda的学习之旅了,但是在说lambda之前必须先说下C#中的匿名方法.

1、匿名方法

下面是一个字符串拼接的程序,用到了委托,代码如下:

    class Program
    {
        static void Main(string[] args)
        {
            string mid = ",middle part,";
            var d1 = new GetString(Test);
            string aa=d1("Start of string") + mid + "this is the End";
            Console.WriteLine(aa);
            Console.ReadLine();

        }
        static string Test(string add)
        {
            return add;
        }
    }

很简单的代码,下面把它用匿名方法来改写,代码如下:

    class Program
    {
        static void Main(string[] args)
        {
            string mid = ",middle part,";
            Func<string, string> func = delegate(string param)
            {
                param += mid;
                param += "The end of string";
                return param;
            };
            Console.WriteLine(func("The Start of String"));
            Console.ReadLine();
        }
    }

匿名方法的优点:

a、减少了要编写的代码,不必定义由委托使用的方法

b、降低了代码的复杂度,尤其是定义了好几个事件时

但是,匿名方法的代码执行速度并没有加快,应为编译器还是会生成一个方法,所以使用匿名方法,还是会有以下限制:

a、在匿名方法中不能使用跳转语句(break、goto、continue)跳转到该匿名方法的外部,反之依然,外部跳转到里面也不能

b、在匿名方法中不能访问不安全的代码,另外也不能在匿名方法外部使用的ref或者out参数,但是可以使用在匿名方法外部定义的其他参数

2、Lamdba表达式

匿名方法虽然好,但是从C#3.0之后,推出了更好的Lamdba表达式,只要有委托参数的地方,就可以使用Lamdba表达式,现在改编上面的匿名方法用Lamdba表达式:

    class Program
    {
        static void Main(string[] args)
        {
            string mid = ",middle part,";
            Func<string, string> func = param =>
                {
                    param += mid;
                    param += "The end of string";
                    return param;
                };
            Console.WriteLine(func("The Start of String"));
            Console.ReadLine();
        }

    }

lamdba运算符"=>"的左边列出了需要的参数,右边定义了关于参数的实现方法体

如果委托有多个参数,就把参数名放到花括号中,代码如下:

    class Program
    {
        static void Main(string[] args)
        {
            Func<double, double, double> func = (x, y) =>
            {
                return x * y;
            };
            Console.WriteLine(func(2, 3));
            Console.ReadLine();
        }

    }

上面的代码可能会存在问题,当编译器不能匹配重载后的版本,那么这个时候,就需要给参数加上类型,代码如下:

    class Program
    {
        static void Main(string[] args)
        {
            Func<double, double, double> func = (double x, double y) =>
            {
                return x * y;
            };
            Console.WriteLine(func(2, 3));
            Console.ReadLine();
        }

    }

当Lamdba表达式方法体只有一行代码时,就不需要中括号,和return关键字,代码如下:

    class Program
    {
        static void Main(string[] args)
        {
            Func<double, double, double> func = (double x, double y) => x * y;
            Console.WriteLine(func(2, 3));
            Console.ReadLine();
        }

    }

但是如果有多行代码就必须加中括号和return关键字了,有点类似与if else语句

2、Lamdba表达式闭包

闭包这个很多编程语言中都有,Lamdba表达式能访问表达式外部的变量就是通过闭包来实现的。闭包是一个非常好用的功能,但是使用不当,也会出现问题。代码如下:

    class Program
    {
        static void Main(string[] args)
        {
            double value1 = 6;
            Func<double, double> func = x => x + value1;
            value1 = 7;
            Console.WriteLine(func(1) + "...." + func(2));
            Console.ReadLine();
        }

    }

输出:8和9并不是我们想的7和8,

原因在编译器处理外部变量的方式:对于lamdba表达式x=>x+value1,编译器会创建一个类,它有一个构造函数来初始化外部参数,

该构造函数的参数个数值取决于外部传递进来的参数个数,代码如下:

    public class AnonymousClass
    {
        private int value1;
        public AnonymousClass(int value1)
        {
            this.value1 = value1;
        }
        public int AnonymousMethod(int x)
        {
            return x + value1;
        }
    }

使用Lamdba表达式并调用该方法时,会创建匿名类的一个实例,并传递调用该方法时变量的值。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C# 字符串类型介绍与操作

    一、关于字符串操作的方法 System.String类提供了很多工具方法,包括返回字符数据长度,查找当前字符串中的子字符串和转换大小写等方法。 ? 在Strin...

    郑小超.
  • C#核编之System.Console类

          顾名思义,Console类封装了基于控制台的输入输出和错误流的操作,下面列举一些System.Console类常用的成员的,这些成员能为简单的命令行...

    郑小超.
  • Common.Logging源码解析一

    Common.Logging是Apache下的一个开源日志接口组件,主要用于切换不同的日志库,因为当前流行的日志库有很多向log4j、log4net(log4j...

    郑小超.
  • package exec

    exec包执行外部命令。它包装了os.StartProcess函数以便更容易的修正输入和输出,使用管道连接I/O,以及作其它的一些调整。

    李海彬
  • 图片中隐藏文件

    sofu456
  • 如何使用云开发部署 Hexo 博客

    在进行后续的内容前,请先确保你的电脑中安装了 Node.js 运行环境。如果没有安装,可以访问 nodejs.org 下载安装。

    腾讯云开发TCB
  • 想实现全网数据的清洗与聚合?从爬虫做起

    本文由腾讯云+社区自动同步,原文地址 http://blogtest.stackoverflow.club/96/

    羽翰尘
  • 一款基于中间人攻击用于偷窥HTTPs网站流量的秘密代理工具

    我常用的网络分析工具有:Fiddler、Charles 、whistle 、WireShark 和 Tcpdump

    快乐咸鱼每一天
  • 机器人PK 无人机:谁才是最好的快递小哥?

    网购今天已经成为多数人一种生活方式,但我们舒舒服服坐等货物的时候,却少不了快递哥和货卡的忙碌。亚马逊推出无人机送货一度令人欢欣鼓舞,现在一个以色列学生又构想了一...

    机器人网
  • MySQL高可用架构-MHA环境部署记录

    一、MHA介绍 MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshim...

    洗尽了浮华

扫码关注云+社区

领取腾讯云代金券