随着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);
}

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

获取Lambda表达式内表达式的值的更多相关文章

  1. EL表达式获取Map和List中的值

    EL表达式获取Map和List中的值   EL表达式取Map中的值: 当Map中是String,String时 后台servlet中: Map<String, String> map1 = ...

  2. 获取lambda表达式类型,获取attributes是注意事项

    1.获取lambda表达式的MemberExpression所属类的类型,要使用:m.Expression.Type   而不要使用 m.Member.DeclaringType: 后者获取的是实际定 ...

  3. 【JSP EL】<c:if> <c:foreach >EL表达式 获取list长度/不用循环,EL在List中直接获取第一项的内容/EL获取Map的键,Map的值

    1.EL表达式 获取list长度 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" ...

  4. C#中的Lambda表达式和表达式树

    在C# 2.0中,通过方法组转换和匿名方法,使委托的实现得到了极大的简化.但是,匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性可能就会受到影响.C# 3.0中出现的Lambda表达式在 ...

  5. Lambda表达式和表达式树

    在C# 2.0中,通过方法组转换和匿名方法,使委托的实现得到了极大的简化.但是,匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性可能就会受到影响.C# 3.0中出现的Lambda表达式在 ...

  6. C#复习笔记(4)--C#3:革新写代码的方式(Lambda表达式和表达式树)

    Lambda表达式和表达式树 先放一张委托转换的进化图 看一看到lambda简化了委托的使用. lambda可以隐式的转换成委托或者表达式树.转换成委托的话如下面的代码: Func<string ...

  7. lambda表达式和表达式树(深入理解c#)

    1.Lambda形式 1). Lambda表达式最冗长的形式: (显式类型的参数列表)=>{语句} 2). 大多数时候,都可以用一个表达式来表示主体,该表达式的值是Lambda的结果,在这些情况 ...

  8. 16.C#初见Lambda表达式及表达式树(九章9.1-9.3)

    在说明Lambda相关知识前,我们需要了解Lambda表达式常用于LINQ,那么我们来聊下LINQ. LINQ的基本功能就是创建操作管道,以及这些操作需要的任何状态.这些操作表示了各种关于数据的逻辑: ...

  9. 深入学习C#匿名函数、委托、Lambda表达式、表达式树类型——Expression tree types

    匿名函数 匿名函数(Anonymous Function)是表示“内联”方法定义的表达式.匿名函数本身及其内部没有值或者类型,但是可以转换为兼容的委托或者表达式树类型(了解详情).匿名函数转换的计算取 ...

随机推荐

  1. vue仿淘宝结账订单

    <template>  <div class="container">  <div class="checkout-title"& ...

  2. VS2015密匙--VS2015打开丢失msvcp140.dll--cannot find one or more components ,please reinstall the application

    win7旗舰版 64位 + vs2015 专业版 1.安装VS2015过程中可能需要用到的VS2015专业版钥匙:(测试,可用) HMGNV-WCYXV-X7G9W-YCX63-B98R2 2.VS2 ...

  3. uva-10041-水题

    题意:有个人想找到个房子住,并且他经常去其他街道,输入n条街,给这个人选择一条街,使得他去其他街道的距离总和最小. 排序,双重for #include <string> #include& ...

  4. ODPS SQL <for 数据操作语言DML>

    基本操作: 查询: SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference [WHERE where_co ...

  5. 修改git以往历史中所有commit的name和email

    当换了新的电脑设备或者在 homestead 中使用 git 的时候:如果忘了 git config 设置用户名和邮箱:这样当 git commit 的时候就会使用设备名作为 git 用户名:或者我们 ...

  6. Linux网络编程学习计划

    由于网络编程是很重要的一块,自己这一块也比较欠缺,只知道一些皮毛,从今天开始系统学习<Linux网络编程>一书,全书分为十四个章节: 第一章   概论   P1-16 第二章   UNIX ...

  7. LAMP架构

    LAMP(linux,apache,mysql,php)是linux系统下常用的网站架构模型,用来运行PHP网站.(这得apache是httpd服务),这些服务可以安装同意主机上,也可以安装不同主机上 ...

  8. 十一、Composite 组合模式

    原理: 代码清单 Entity public abstract class Entry { public abstract String getName(); public abstract int ...

  9. day37 异步回调和协程

    异步回调 """ 异步任务使用场景 爬虫 1.从目标站点下载网页数据 本质就是HTML格式字符串 2.用re从字符串中提取出你需要的数据 ""&quo ...

  10. 关于C语言头文件写法的探讨

    我不是软件工程出身,对于这方面一直处于探索阶段. 目前按照这样的习惯吧. 除主函数所在的文件以外,为每一个源文件配置一个头文件. 头文件里面不能写变量的申明和定义.头文件里面只写 #define,st ...