什么是Lambda表达式?我们可以认为它是匿名方法的简洁写法,例如下面这个匿名方法:
1: delegate(int age)
2: {
3: return age < 18;
4: }
我们就可以写成Lambda表达式的形式:
1: age => age < 18
这是一个很简单的例子,基本上一目了然。Lambda的基本形式是argument-list => expression,=>是Lambda表达式的标识符而不是运算符,显而易见,=>的作用就是{}花括号的作用,与此同时,我们看到了在Lambda表达式中被省略掉的还有参数声明中的数据类型和return关键字以及句尾的分号,因为它们在Lambda表达式中不是必需的,在有参数的情况下表达式总是会返回一个值,而没有参数的情况下表达式也可以不必返回任何值,参数的数据类型是靠编译器从右边的表达式中反推出来的,另外,=>右边只是一个表达式而不是一句完整的语句,所以如果画蛇添足地加上分号就违背了语法规则。当然,右边的表达式中也是可以包含多条语句的,这时候语句之间依然采用分号来分割,但前提是这些语句都要被放置在一对{}花括号里面,不过我的建议还是在语句较少功能较简单的时候才只用Lambda表达式,否则写出来的代码在可读性方面可能会比较差,为以后的维护和修改工作带来不必要的麻烦,要像对待内联函数一样对待Lmbda表达式。
在单个参数的Lambda表达式中我们可以省略参数列表部分的小括号,但是多个参数或者没有参数以及需要显式地为参数设置数据类型的情况下,小括号就不能省略了,例如:
1: // No parameter.
2: () => Console.WriteLine("Hello, world!")
3:
4: // Multiple parameters.
5: (m, n) => m = n * 10
6:
7: // Explicitly typed declaration.
8: (int age) => age < 18
那么我们什么时候用Lambda表达式呢?很简单,前面说过我们可以认为Lambda表达式就是匿名方法的简洁写法,所以原先采用匿名方法的地方现在我们就可以替换成Lambda表达式了。
同样的,如果一些事件发生的时候我们只想做一点儿简单的事情的话,那么也可用Lambda表达式来实现:
1: System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
2: timer.Interval = 2000;
3: timer.Tick += (sender, e) => { timer.Stop(); MessageBox.Show("Hello, Lambda Expression!"); };
最后我们来看一段比较完整的代码并以此结束对Lambda表达式的介绍吧:
1: using System;
2: using System.Collections.Generic;
3:
4: namespace LambdaExpressionDemo
5: {
6: class Program
7: {
8: private static List<StudentData> _class = null;
9:
10: static void Initialization()
11: {
12: _class = new List<StudentData>();
13:
14: _class.Add(new StudentData("ZeroCool", 24, GenderType.Male, 87));
15: _class.Add(new StudentData("Michael", 24, GenderType.Male, 93));
16: _class.Add(new StudentData("Frieda", 22, GenderType.Female, 98));
17: _class.Add(new StudentData("Somebody", 23, GenderType.Male, 81));
18: }
19:
20: static void Main(string[] args)
21: {
22: Initialization();
23:
24: if (_class == null || _class.Count == 0)
25: {
26: throw new InvalidOperationException("The system initialization was failed.");
27: }
28:
29: StudentData studentData = _class.Find(student => student.MathScore >= 90 && student.MathScore < 95);
30: RepresentData(studentData);
31:
32: studentData = _class.Find(student => student.Name.Equals("ZeroCool", StringComparison.InvariantCultureIgnoreCase));
33: RepresentData(studentData);
34:
35: studentData = _class.Find(student => student.Age < 23);
36: RepresentData(studentData);
37:
38: Console.ReadLine();
39: }
40:
41: static void RepresentData(StudentData student)
42: {
43: if (student == null)
44: {
45: Console.WriteLine("No mached student.");
46:
47: return;
48: }
49:
50: Console.WriteLine("Name:/t/t" + student.Name);
51: Console.WriteLine("Age:/t/t" + student.Age);
52: Console.WriteLine("Gender:/t/t" + student.Gender.ToString());
53: Console.WriteLine("Math Score:/t" + student.MathScore);
54: Console.WriteLine();
55: }
56: }
57:
58: public enum GenderType
59: {
60: Male = 0,
61: Female
62: }
63:
64: public class StudentData
65: {
66: private string _name = String.Empty;
67: public string Name
68: {
69: get { return this._name; }
70: set { this._name = value; }
71: }
72:
73: private int _age = 0;
74: public int Age
75: {
76: get { return this._age; }
77: set { this._age = value; }
78: }
79:
80: private GenderType _gender;
81: public GenderType Gender
82: {
83: get { return this._gender; }
84: set { this._gender = value; }
85: }
86:
87: private int _mathScore = 0;
88: public int MathScore
89: {
90: get { return this._mathScore; }
91: set { this._mathScore = value; }
92: }
93:
94: public StudentData()
95: {
96: }
97:
98: public StudentData(string name, int age, GenderType gender, int mathScore)
99: {
100: this._name = name;
101: this._age = age;
102: this._gender = gender;
103: this._mathScore = mathScore;
104: }
105:
106: public delegate void EmptyDelegate();
107:
108: EmptyDelegate dl = () => Console.WriteLine();