• 获取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);
    }
    

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

  • 相关阅读:
    20169210《Linux内核原理与分析》第十周作业
    Collabtive 系统 SQL 注入实验(补充)
    20169211《Linux内核原理与分析》课程总结
    20169211《Linux内核原理及分析》第十二周作业
    20169211 《Linux内核原理与分析》第十一周作业
    20169211《Linux内核原理与分析》 第十周作业
    20169211《Linux内核原理与分析》 第九周作业
    20169210《Linux内核原理与分析》第八周作业
    20169211《linux内核原理与分析》第七周作业
    20169211《Linux内核原理与分析》第六周作业
  • 原文地址:https://www.cnblogs.com/ahl5esoft/p/3213792.html
Copyright © 2020-2023  润新知