Lambda表达式也是C#3.0中最重要的特性之一。
1、Lambda表达式的简介
Lambda表达式可以理解为一个匿名方法,它可以包含表达式和语句,并且用于创建委托或转换为表达式树。在使用Lambda表达式时,都会使用“=>”运算符,该运算符的左边是匿名方法的输入参数,右边则是表达式或语句块。
1.1 Lambda表达式的演变过程
其实Lambda表达式是匿名方法的投胎转世。下面以代码来鉴定:
1 C# 1.0
2 Func<string,int> delegatetest1=new Func<string,int>(Callbackmethod);
3
4 C# 2.0
5 Func<string,int> delegatetest2=delegate(string text)
6 {
7 return text.Length;
8 }
9
10 C# 3.0
11 Func<string,int> delegatetest3=(string text)=>text.Length;
12
13 可以省略参数类型string,从而将代码再次简化
14 Func<string,int> delegatetest4=(text)=text.Length;
15 此时也可以把圆括号省略
16 Func<string,int> delegatetest=text=>text.Length;
以上代码形象地掩饰了Lambda表达式是如何由匿名方法演变而来的。
1.2 Lambda表达式的使用
在实际开发过程中,委托的用途莫过于订阅事件了。为了加深大家对Lambda表达式的理解,这里选择演示用Lambda表达式去订阅事件。
1 namespace Lambda表达式
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 Button button1 = new Button() {Text = "点击我"};
8 button1.Click += (sender, e) => ReportEvent("Click事件", sender, e);
9 button1.KeyPress += (sender, e) => ReportEvent("KeyPress事件", sender, e);
10 }
11
12 private static void ReportEvent(string s, object sender, EventArgs eventArgs)
13 {
14 throw new NotImplementedException();
15 }
16 }
17 }
从以上代码可以看出,使用了C# 3.0的对象初始化器和Lambda表达式后,代码确实简洁了不少。
2、表达式也有树结构——表达式树
Lambda表达式除了可以用来创建委托外,还可以转换成表达式树。表达式树(或称“表达式目录树”)是用来表示Lambda表达式逻辑的一种数据结构,它将代码表示成一个对象树,而非可执行代码。其实可以将表达式树理解为一种数据结构,类似栈或队列这种。
2.1 通过Lambda表达式来构造表达式树
1 namespace 表达式树
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 //将Lambda表达式构造成表达式树
8 Expression<Func<int, int, int>> expressionTree = (a, b) => a + b;
9
10 //获得表达式树参数
11 Console.WriteLine($"参数1:{expressionTree.Parameters[0]},参数2:{expressionTree.Parameters[1]}");
12
13 //获取表达式树的主体部分
14 BinaryExpression body = (BinaryExpression) expressionTree.Body;
15
16 //左节点(每个节点本身就是一个表达式对象)
17 ParameterExpression left = (ParameterExpression) body.Left;
18
19 //右节点
20 ParameterExpression right = (ParameterExpression)body.Right;
21
22 Console.WriteLine("表达式树主体为:");
23 Console.WriteLine(expressionTree.Body);
24 Console.WriteLine($"表达式树左节点为:{left.Name}{Environment.NewLine} 节点类型为:{left.Type}{Environment.NewLine}{Environment.NewLine} 表达式树右节点为:{right.Name}{Environment.NewLine} 节点类型为:{right.Type}{Environment.NewLine}");
25 Console.ReadKey();
26
27 }
28 }
29 }
从以上代码可以看出,通过Lambda表达式来构造表达式树的过程非常简单,只需要把Lambda表达式赋给一个表达式树变量就可以了。
2.2 如何把表达式树转换成可执行代码
1 namespace 表达式树2
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 //将Lambda表达式构造成表达式树
8 Expression<Func<int, int, int>> expressionTree = (a, b) => a + b;
9 //通过调用complie方法来生成Lambda表达式的委托
10 Func<int, int, int> delinstance = expressionTree.Compile();
11 //调用委托实例获得结果
12 int result = delinstance(1, 2);
13 Console.WriteLine($"2和3的和为:{result}");
14 Console.ReadKey();
15 }
16 }
17 }
以上代码通过Expression<TDelegate>类的Compile()方法将表达式树编译成委托实例,然后通过委托调用的方式得到两个数的和。