不一样的编码风格--Lambda表达式

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()方法将表达式树编译成委托实例,然后通过委托调用的方式得到两个数的和。

posted @ 2016-08-14 22:54  Helius-黑牛  阅读(746)  评论(0编辑  收藏  举报