• [.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门


    [.net 面向对象程序设计进阶] (6) Lamda表达式(表达式树快速入门

    本节导读:

    认识表达式树(Expression Tree),学习使用Lambda创建表达式树,解析表达式树。

    学习表达式在程序设计中的优点:比如构造动态查询、动态构造表达式树完成未知对象属性访问,比反射的性能高出很多。我们可以说表达式树才是Lambda的精髓,是我们必须要熟练掌握并灵活运用的。 

    1.关于表达式树(Expression Tree) 

    表达式树以树形数据结构表示代码,其中每一个节点都是一种表达式,比如方法调用和 x < y 这样的二元运算等。 

    表达式树,对于刚接触的人来说,比较难以理解。那么什么是表达式树,通俗点来说,就是使用一种树形的数据结构来缓存表达式。 

    2.表达式树能帮我们做点什么? 

    面我们说了表达式树是一种数据结构,那么为什么要把表达式定义成表达式树呢,转成一种数据结构,能帮我们做点什么?先明确了他能为我们带来什么,才有动力继续看下去。 

    说到他的作用,当然是非常有用的,我们在很多场景下都要使用他,当表达式变为一个表达式树的数据结构时,表达式就变为一个对象,你可以对表达式树中的对象元素(表达式的代码)进行编辑和运算。下面列举几种常用的: 

    1. 通过修改表达式树能够动态修改可执行代码
    2. 在不同数据库中执行 LINQ 查询
    3. 创建动态查询。
    4. 完成类似反射访问未知对象属性,通过动态构造表达式树,生成委托。 

    3. 表达式树的创建 

    命名空间: System.Linq.Expressions  

    创建表达式树示例: 

    Expression<Func<int, int, bool>>  expression  =  (num,num2)=> num < num2;

    这个语句包含三个部分: 

    1. 一个声明Func<int, int, int> function
    2. 一个等号: =
    3. 一个lambda表达式(num,num2)=> num < num2; 

    expression 就是一个类型为Expression<T>的表达式树,可以看出,他并非是一个可执行代码,而是一种表达式树的数据结构。 

     4. 表达式树结构的构成 

    Expression<Func<int, int, bool>>  expression  =  (num,num2)=> num < num2;

    通过监视我们定义好的表达式树,可以看到其构成 

     下面我们对几个重要属性说明: 

    • Body: 得到表达式的主体例:(num < num2)    其中,Body中又包含属性Left和Right  在上例中分别为num和num2
    • Parameters: 得到lambda表达式的参数。 例 {num,num2}
    • NodeType: 获取树的节点的ExpressionType。共45种不同值,包含所有表达式节点各种可能的类型。例如返回常量,例如返回参数,例如取两个值的小值(<),例如取两个值的大值(>),例如将值相加(+),等等。例:Lambda
    • Type: 获取表达式的一个静态类型 例:Func<int, int, bool>  
    • ReturnType:这个是表达式的返回类型   例:bool 

    还有一些其他属性Name、CanReduce等,这些不是很常用。  

    5.解析表达式树 

      我们了解了表达式树结构的组成,解析表达式变得相当容易了,下面我们直接通过一个示例来完成对一个表达式树的解析:  

    //表达式树(Expression)
    Expression<Func<int, int, bool>> expression = (x, y) => x!=0 && x==y+1;
    
    BinaryExpression exr = expression.Body as BinaryExpression;
    IReadOnlyList<ParameterExpression> param = expression.Parameters as IReadOnlyList<ParameterExpression>;
    BinaryExpression left = exr.Left as BinaryExpression;
    BinaryExpression right = exr.Right as BinaryExpression;
    ExpressionType exrType = exr.NodeType;
    
    ParameterExpression leftLeft = left.Left as ParameterExpression;
    ConstantExpression leftRight = left.Right as ConstantExpression;
    ExpressionType leftType = left.NodeType;
    
    ParameterExpression rightLeft = right.Left as ParameterExpression;
    BinaryExpression rightRight = right.Right as BinaryExpression;
    ExpressionType rightType = right.NodeType;
    
    ParameterExpression rightRightLeft = rightRight.Left as ParameterExpression;
    ExpressionType rightRightType = rightRight.NodeType;
    ConstantExpression rightRightRight = rightRight.Right as ConstantExpression;          
    
    Console.WriteLine(exr.ToString());

     表达式树的解析,里面的元素无非就下面几种:  

    A.BinaryExpression 包含二元运算符的表达式 

    B.ParameterExpression命名的参数表达式 ,一般是一组参数集合IReadOnlyList<ParameterExpression> 

    C.ConstantExpression常量值的表达式 

    D.ExpressionType节点类型 

    对于上面示例的表达树结构,我用图例的方式展现如下:

      

    对于上面的结构,我们可以按上面代码中的对象元素变量与之一一对应如下图:  

     

    要点:

    本节我们介绍了表达式树在.NET面向对象程序设计中的作用、表达式树的创建与解析,相信小伙伴们对表达式树这种结构比较了解了。

    表达式树(Expression Tree)就是一种使用对象的方式来描述表达式。这也正是.NET一切皆是对象的思想体现。 

    下一节我们会介绍动态创建一个表达式树结构、会举列说明几种表达式树在.NET程序设计中的应用。

    ==============================================================================================  

     返回目录

     <如果对你有帮助,记得点一下推荐哦,如有有不明白或错误之处,请多交流>  

    <对本系列文章阅读有困难的朋友,请先看《.net 面向对象编程基础》>

    <转载声明:技术需要共享精神,欢迎转载本博客中的文章,但请注明版权及URL>

    .NET 技术交流群:467189533    .NET 程序设计

    ==============================================================================================   

  • 相关阅读:
    Agilent RF fundamentals (7) Oscillator characterization
    Agilent RF fundamentals (6)
    L136
    Agilent RF fundamentals (5)
    Agilent RF fundamentals (4)- Impedance match and distortions
    L134
    2018.9.14 长难句1
    L133
    PyQt(Python+Qt)学习随笔:QTreeWidget中给树型部件增加顶层项的方法
    PyQt(Python+Qt)学习随笔:invisibleRootItem方法访问QTreeWidget树型部件的隐形根节点
  • 原文地址:https://www.cnblogs.com/yubinfeng/p/4621426.html
Copyright © 2020-2023  润新知