zoukankan      html  css  js  c++  java
  • 不一样的编码风格--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()方法将表达式树编译成委托实例,然后通过委托调用的方式得到两个数的和。

  • 相关阅读:
    4、2 核心组件
    promise
    Content-Type
    $routeProvider
    广告
    $apply() $digest()
    异常
    switch
    autoprefixer
    $resource
  • 原文地址:https://www.cnblogs.com/Helius/p/5771317.html
Copyright © 2011-2022 走看看