• 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表达式并调用该方法时,会创建匿名类的一个实例,并传递调用该方法时变量的值。

  • 相关阅读:
    Django之web本质
    Python之队列
    Python之阻塞IO模型与非阻塞IO模型
    *****Python之进程线程*****
    ***Python之UDP***
    Python之FTP实现
    Python之粘包
    Python之目录结构
    Python之套接字
    Linux内核分析:Linux内核启动流程分析
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/7070757.html
Copyright © 2020-2023  润新知