关键词搜索

源码搜索 ×
×

C# Lambda表达式学习笔记

发布2020-12-13浏览321次

详情内容

本笔记摘抄自:https://www.cnblogs.com/leslies2/archivehttps://cdn.jxasp.com:9143/image/2012/03https://cdn.jxasp.com:9143/image/22https://cdn.jxasp.com:9143/image/2389318.html,记录一下学习过程以备后续查用。

一、Lambda 的意义

在Framework 2.0 以前,声明委托的唯一方法是通过方法命名,从Framework 2.0 起,系统开始支持匿名方法。通过匿名方法,可以直接把一段代码绑定

    给事件,因此减少了实例化委托所需的编码系统开销。而在 Framework 3.0 开始,Lambda表达式开始逐渐取代了匿名方法,作为编写内联代码的首选方式。

    总体来说,Lambda 表达式的作用是为了使用更简单的方式来编写匿名方法,彻底简化委托的使用方式。
    
    二、回顾匿名方法的使用
    
    匿名方法的使用在C#委托与事件学习笔记中有简单介绍过,在此回顾一下:
    
              static void Main(string[] args)
              {
                  #region 事件的使用及方法绑定
                  PersonManager personManager = new PersonManager();
                  //绑定事件处理方法方式一
                  personManager.MyEvent += new MyDelegate(GetName);
                  //绑定事件处理方法方式二
                  personManager.MyEvent += GetName;
                  //绑定事件处理方法方式三(匿名方法)
                  personManager.MyEvent += delegate (string name) { Console.WriteLine("My name is " + name); };
                  personManager.Execute("Atomy");
                  Console.Read();
                  #endregion
              }
      
        6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      总是使用 delegate(){......} 的方式建立匿名方法,令人不禁感觉郁闷。于是从Framework 3.0起,Lambda表达式开始出现。
      
      三、简单介绍泛型委托
      
      在介绍Lambda表达式前,先介绍一下常用的几个泛型委托。
      
      3.1 泛型委托 Predicate<T>
      
      早在Framework 2.0的时候,微软就为List<T>类添加了Find、FindAll、ForEach等方法用作数据的查找。
      
        6
      • 7
      • 8
      • 9
      public T Find ( Predicate<T> match)
      
      public List<T> FindAll(Predicate<T>  match)
      
      • 1
      • 2
      • 3
      在这些方法中存在一个Predicate <T> 表达式,它是一个返回bool的泛型委托,能接受一个任意类型的对象作为参数。
      
      public delegate bool Predicate<T>(T obj)
      
      在下面例子中,Predicate委托绑定了参数为Person类的方法Match作为查询条件,然后使用FindAll方法查找到合适条件的List<Person>集合。
      
            class Program
            {
                #region 泛型委托 Predicate<T>
                /// <summary>
                /// Person类
                /// </summary>
                class Person
                {
                    public int Id { get; set; }
                    public string Name { get; set; }
                    public int Age { get; set; }
        
                    public Person(int id, string name, int age)
                    {
                        Id = id;
                        Name = name;
                        Age = age;
                    }
                }
        
                /// <summary>
                /// 数据源
                /// </summary>
                /// <returns></returns>
                static List<Person> GetList()
                {
                    var personList = new List<Person>();
                    var person = new Person(1, "Hello", 29);
                    personList.Add(person);
                    person = new Person(1, "World", 31);
                    personList.Add(person);
                    return personList;
                }
        
                /// <summary>
                /// 查询条件
                /// </summary>
                /// <param name="person"></param>
                /// <returns></returns>
                static bool Match(Person person)
                {
                    return person.Age <= 30;
                }
                #endregion
        
                static void Main(string[] args)
                {
                    #region 泛型委托 Predicate<T>
                    List<Person> list = GetList();
                    //绑定查询条件
                    Predicate<Person> predicate = new Predicate<Person>(Match);
                    List<Person> result = list.FindAll(predicate);
                    Console.WriteLine($"Person count is : {result.Count}");
                    Console.Read();
                    #endregion
                }
            }
        
          6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
        • 39
        • 40
        • 41
        • 42
        • 43
        • 44
        • 45
        • 46
        • 47
        • 48
        • 49
        • 50
        • 51
        • 52
        • 53
        • 54
        • 55
        • 56
        • 57
        运行结果如下:
        
        • 1

        在这里插入图片描述

        3.2 泛型委托 Action
        
        Action<T> 的使用方式与 Predicate<T> 相似,不同之处在于 Predicate<T> 返回值为 bool ,  Action<T> 的返回值为 void。
        
        Action 支持0~16个参数,可以按需求任意使用。
        
              public delegate void Action()
          
              public delegate void Action<T1> (T1 obj1)
          
              public delegate void Action<T1T2> (T1 obj1, T2 obj2)
          
              public delegate void Action<T1T2T3> (T1 obj1, T2 obj2,T3 obj3)
          
              ............
          
              public delegate void Action<T1T2T3......T16> (T1 obj1, T2 obj2,T3 obj3,......T16 obj16)
          
            6
          • 7
          • 8
          • 9
          • 10
          • 11
          下面代码演示泛型委托Action:
          
          • 1
              class Program
              {
                  #region 泛型委托 Action
                  static void ShowMessage(string message)
                  {
                      Console.WriteLine(message);
                  }
                  #endregion
          
                  static void Main(string[] args)
                  {
                      #region 泛型委托 Action
                      Action<string> action = ShowMessage;
                      action("Hello World");
                      Console.ReadKey();
                      #endregion
                  }
              }
          
            6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          运行结果如下:
          
          • 1

          在这里插入图片描述

          3.3 泛型委托 Func
          
          委托Func与Action相似,同样支持0~16个参数,不同之处在于Func必须具有返回值。
          
          • 1
          • 2
          • 3
              public delegate TResult Func<TResult>()
          
              public delegate TResult Func<T1,TResult>(T1 obj1)
          
              public delegate TResult Func<T1,T2,TResult>(T1 obj1,T2 obj2)
          
              public delegate TResult Func<T1,T2,T3,TResult>(T1 obj1,T2 obj2,T3 obj3)
          
              ............
          
              public delegate TResult Func<T1,T2,T3,......,T16,TResult>(T1 obj1,T2 obj2,T3 obj3,......,T16 obj16)
          
            6
          • 7
          • 8
          • 9
          • 10
          • 11
          下面代码演示泛型委托Func:
          
          • 1
              class Program
              {
                  #region 泛型委托 Func
                  static double Account(double a, bool condition)
                  {
                      if (condition)
                          return a * 1.5;
                      else
                          return a * 2;
                  }
                  #endregion
          
                  static void Main(string[] args)
                  {
                      #region 泛型委托 Func
                      Func<double, bool, double> func = Account;
                      double result = func(1000, true);
                      Console.WriteLine($"Result is : {result}");
                      Console.Read();
                      #endregion
                  }
              }
          
            6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          运行结果如下:
          
          • 1

          在这里插入图片描述

          四、揭开 Lambda 神秘的面纱
          
          Lambda的表达式的编写格式如下:x=> x * 1.5
          
          当中 “ => ”是Lambda表达式的操作符,在左边用作定义一个参数列表,右边可以操作这些参数。
          
          例子一:先把int x设置1000,通过Action把表达式定义为x=x+500,最后通过Invoke激发委托。
          
            6
          • 7
              class Program
              {
                  static void Main(string[] args)
                  {
                      #region Lambda例子一
                      int x = 1000;
                      Action action = () => x = x + 500;
                      action.Invoke();
          
                      Console.WriteLine($"Result is : {x}");
                      Console.Read();
                      #endregion
                  }
              }
          
            6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          运行结果如下:
          
          • 1

          在这里插入图片描述

          例子二:通过Action<int>把表达式定义x=x+500,到最后输入参数1000,得到的结果与例子一相同。
          
          注意,此处Lambda表达式定义的操作使用{ }括弧包括在一起,里面可以包含一系列的操作。
          
          • 1
          • 2
          • 3
              class Program
              {
                  static void Main(string[] args)
                  {
                      #region Lambda例子二
                      Action<int> action = (x) =>
                      {
                          x = x + 500;
                          Console.WriteLine($"Result is : {x}");
                      };
                      action.Invoke(1000);
                      Console.Read();
                      #endregion
                  }
              }
          
            6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          运行结果如下:
          
          • 1

          > 这里是引用

          例子三:定义一个Predicate,当输入值大约等于1000则返回true,否则返回false。与3.1的例子相比,Predicate的绑定不需要显式建立一个方法,

          而是直接在Lambda表达式里完成,简洁方便了不少。

              class Program
              {
                  static void Main(string[] args)
                  {
                      #region Lambda例子三
                      Predicate<int> predicate = (x) =>
                      {
                          if (x >= 1000)
                              return true;
                          else
                              return false;
                      };
                      bool result = predicate.Invoke(500);
                      Console.WriteLine($"Result={result}");
                      Console.Read();
                      #endregion
                  }
              }
          
            6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18

          运行结果如下:
          在这里插入图片描述

          例子四:在计算商品的价格时,当商品重量超过30kg则打9折,其他按原价处理。此时可以使用Func<double,int,double>,参数1为商品原价,参数2为商品
          
          • 1

          重量,最后返回值为 double 类型。

              class Program
              {
                  static void Main(string[] args)
                  {
                      #region Lambda例子四
                      Func<double, int, double> func = (price, weight) =>
                      {
                          if (weight >= 30)
                              return price * 0.9;
                          else
                              return price;
                      };
                      double totalPrice = func(200.0, 40);
                      Console.WriteLine($"TotalPrice={totalPrice}");
                      Console.Read();
                      #endregion
                  }
              }
          
            6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          运行结果如下:
          
          • 1

          在这里插入图片描述

          例子五:使用Lambda为Button定义Click事件的处理方法,使用Lambda比使用匿名方法更加简单。
          
          • 1
              public partial class Main : Form
              {
                  public Main()
                  {
                      InitializeComponent();
                  }
          
                  private void Main_Load(object sender, EventArgs e)
                  {
                      #region Lambda例子五
                      btnEvent.Click += (obj,arg)=>
                      {
                          MessageBox.Show("Hello World");
                      };
                      #endregion
                  }
              }
          
            6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          运行结果如下:
          
          • 1

          在这里插入图片描述

          例子六:此处使用3.1的例子,在List<Person>的FindAll方法中直接使用Lambda表达式。相比之下,使用Lambda表达式,不需要定义Predicate<T>对象,也
          
          • 1

          不需要显式设定绑定方法,简化了不工序。

              class Program
              {
                  #region 泛型委托 Predicate<T>
                  /// <summary>
                  /// Person类
                  /// </summary>
                  class Person
                  {
                      public int Id { get; set; }
                      public string Name { get; set; }
                      public int Age { get; set; }
          
                      public Person(int id, string name, int age)
                      {
                          Id = id;
                          Name = name;
                          Age = age;
                      }
                  }
          
                  /// <summary>
                  /// 数据源
                  /// </summary>
                  /// <returns></returns>
                  static List<Person> GetList()
                  {
                      var personList = new List<Person>();
                      var person = new Person(1, "Hello", 29);
                      personList.Add(person);
                      person = new Person(1, "World", 31);
                      personList.Add(person);
                      return personList;
                  }
          
                  /// <summary>
                  /// 查询条件
                  /// </summary>
                  /// <param name="person"></param>
                  /// <returns></returns>
                  static bool Match(Person person)
                  {
                      return person.Age <= 30;
                  }
                  #endregion
          
                  static void Main(string[] args)
                  {
                      #region Lambda例子六
                      List<Person> personList = GetList();
                      //查找年龄少于30年的人
                      List<Person> result = personList.FindAll((person) => person.Age <= 30);
                      Console.WriteLine("Person count is : " + result.Count);
                      Console.Read();
                      #endregion
                  }
              }
          
            6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          运行结果如下:
          
          • 1

          在这里插入图片描述

          当在使用LINQ技术的时候,到处都会弥漫着Lambda的身影,此时更能体现Lambda的长处。但LINQ涉及到分部类、分部方法、IEnumerable<T>、迭代器等
          
          • 1

          多方面的知识,这些已经超出本章的介绍范围。通过这一节的介绍,希望能够帮助大家更深入地了解Lambda的使用。

          相关技术文章

          点击QQ咨询
          开通会员
          返回顶部
          ×
          微信扫码支付
          微信扫码支付
          确定支付下载
          请使用微信描二维码支付
          ×

          提示信息

          ×

          选择支付方式

          • 微信支付
          • 支付宝付款
          确定支付下载