zoukankan      html  css  js  c++  java
  • 获取Lambda表达式内表达式的值

      随着Linq的盛行,对于Linq和Lmabda表达式的使用也越来越多,Lambda表达式在.net framework 3.5中提出来,Lambda表达式是一个匿名方法,通常在LINQ中被用来创建委托,但是当我们利用Lmabda表达式来实现某些操作的时候,分解内部的表达式树结构就很重要了,例如我们要在一些方法调用当中直接使用 t => t.Name 的方式将属性Name获取出来,这样我们就不用自己去写字符串,且在属性发生改变的时候编译器可以帮助我们进行重构和检测。

      当我们要实现以上方式的时候,就不再只是匿名委托了,而是要使用到Expression,它位于System.Linq.Expressions命名空间内,具体的资料大家可以到MSDN内找到,这里就不具体列出来了。在表达式内{ 类.属性 }的格式是一个MemberExpression对象,节点类型是MemberAccess,由于我们要获取的属性对应的类型不一定都一样,因此获取属性名的委托就只能定义为Func<T, object>了,大致代码如下:

    public static string ResloveName<T>(Expression<Func<T, object>> expression)
    {
        var exp = expression.Body as MemberExpression;
        string expStr = exp.ToString();
        return expStr.Substring(expStr.IndexOf(".") + 1);
    }
    

       现在有如下代码:

    User user = new User { Name = "Xiao Ming" };
    Expression<Func<User, bool>> exp = u => u.Name == user.Name;
    

      假如要利用这个二元表达式来构建SQL的话,应该如何去分解这个表达式呢,我的做法是首先将表达式的主体转化为BinaryExpression,然后分别去判断Left、Right属性内的表达式(Left、Right属性表达式都是MemberExpression)的Expression是否跟exp的参数表达式相同,将不同的表达式的值计算出来,用于当作参数,大致代码如下:

    BinaryExpression binaryExp = exp.Body as BinaryExpression;
    Expression constantExp = (binaryExp.Left as MemberExpression).Expression == exp.Parameters[0] ? binaryExp.Right : binaryExp.Left;
    string value = Expression.Lambda(constantExp).Compile().DynamicInvoke().ToString();
    

      从继承体系上看,可以发现所有泛型表达式都是继承自LambdaExpression的,因此可以重载一个方法,大致代码如下:

    public static string ResloveName(Expression<Func<T, object>> expression)
    {
        return ResloveName(expression as LambdaExpression);
    }
    
    public static string ResloveName(LambdaExpression expression)
    {
        var exp = expression.Body as MemberExpression;
        string expStr = exp.ToString();
        return expStr.Substring(expStr.IndexOf(".") + 1);
    }
    

       希望以上的代码能帮助大家在表达式的应用方面有所帮助,谢谢!

  • 相关阅读:
    前端基础进阶(十一):详细图解jQuery对象,以及如何扩展jQuery插件
    前端基础进阶(十):面向对象实战之封装拖拽对象
    前端基础进阶(九):详解面向对象、构造函数、原型与原型链
    前端基础进阶(八):深入详解函数的柯里化
    前端基础进阶(七):函数与函数式编程
    前端基础进阶(六):在chrome开发者工具中观察函数调用栈、作用域链与闭包
    前端基础进阶(五):全方位解读this
    lvs健康检查脚本第三版
    rsync同步常用命令
    nginx启动脚本
  • 原文地址:https://www.cnblogs.com/ahl5esoft/p/3213792.html
Copyright © 2011-2022 走看看