本笔记摘抄自:https://www.cnblogs.com/leslies2/archive/2012/03/22/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 }
总是使用 delegate(){......} 的方式建立匿名方法,令人不禁感觉郁闷。于是从Framework 3.0起,Lambda表达式开始出现。
三、简单介绍泛型委托
在介绍Lambda表达式前,先介绍一下常用的几个泛型委托。
3.1 泛型委托 Predicate
早在Framework 2.0的时候,微软就为List
public T Find ( Predicate
public List
在这些方法中存在一个Predicate
public delegate bool Predicate
在下面例子中,Predicate委托绑定了参数为Person类的方法Match作为查询条件,然后使用FindAll方法查找到合适条件的List
class Program { #region 泛型委托 Predicate/// /// Person类 /// 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; } } /// /// 数据源 /// /// static List GetList() { var personList = new List (); var person = new Person(1, "Hello", 29); personList.Add(person); person = new Person(1, "World", 31); personList.Add(person); return personList; } /// /// 查询条件 /// /// /// static bool Match(Person person) { return person.Age <= 30; } #endregion static void Main(string[] args) { #region 泛型委托 Predicate List list = GetList(); //绑定查询条件 Predicate predicate = new Predicate (Match); List result = list.FindAll(predicate); Console.WriteLine($"Person count is : {result.Count}"); Console.Read(); #endregion } }
运行结果如下:
3.2 泛型委托 Action
Action
Action 支持0~16个参数,可以按需求任意使用。
public delegate void Action()
public delegate void Action
public delegate void Action
public delegate void Action
............
public delegate void Action
下面代码演示泛型委托Action:
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 } }
运行结果如下:
3.3 泛型委托 Func
委托Func与Action相似,同样支持0~16个参数,不同之处在于Func必须具有返回值。
public delegate TResult Func
public delegate TResult Func
public delegate TResult Func
public delegate TResult Func
............
public delegate TResult Func
下面代码演示泛型委托Func:
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 } }
运行结果如下:
四、揭开 Lambda 神秘的面纱
Lambda的表达式的编写格式如下:x=> x * 1.5
当中 “ => ”是Lambda表达式的操作符,在左边用作定义一个参数列表,右边可以操作这些参数。
例子一:先把int x设置1000,通过Action把表达式定义为x=x+500,最后通过Invoke激发委托。
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 } }
运行结果如下:
例子二:通过Action
注意,此处Lambda表达式定义的操作使用{ }括弧包括在一起,里面可以包含一系列的操作。
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 } }
运行结果如下:
例子三:定义一个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 } }
运行结果如下:
例子四:在计算商品的价格时,当商品重量超过30kg则打9折,其他按原价处理。此时可以使用Func
重量,最后返回值为 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 } }
运行结果如下:
例子五:使用Lambda为Button定义Click事件的处理方法,使用Lambda比使用匿名方法更加简单。
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 } }
运行结果如下:
例子六:此处使用3.1的例子,在List
不需要显式设定绑定方法,简化了不工序。
class Program { #region 泛型委托 Predicate/// /// Person类 /// 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; } } /// /// 数据源 /// /// static List GetList() { var personList = new List (); var person = new Person(1, "Hello", 29); personList.Add(person); person = new Person(1, "World", 31); personList.Add(person); return personList; } /// /// 查询条件 /// /// /// static bool Match(Person person) { return person.Age <= 30; } #endregion static void Main(string[] args) { #region Lambda例子六 List personList = GetList(); //查找年龄少于30年的人 List result = personList.FindAll((person) => person.Age <= 30); Console.WriteLine("Person count is : " + result.Count); Console.Read(); #endregion } }
运行结果如下:
当在使用LINQ技术的时候,到处都会弥漫着Lambda的身影,此时更能体现Lambda的长处。但LINQ涉及到分部类、分部方法、IEnumerable
多方面的知识,这些已经超出本章的介绍范围。通过这一节的介绍,希望能够帮助大家更深入地了解Lambda的使用。