获取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);
}
希望以上的代码能帮助大家在表达式的应用方面有所帮助,谢谢!
获取Lambda表达式内表达式的值的更多相关文章
- EL表达式获取Map和List中的值
EL表达式获取Map和List中的值 EL表达式取Map中的值: 当Map中是String,String时 后台servlet中: Map<String, String> map1 = ...
- 获取lambda表达式类型,获取attributes是注意事项
1.获取lambda表达式的MemberExpression所属类的类型,要使用:m.Expression.Type 而不要使用 m.Member.DeclaringType: 后者获取的是实际定 ...
- 【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" ...
- C#中的Lambda表达式和表达式树
在C# 2.0中,通过方法组转换和匿名方法,使委托的实现得到了极大的简化.但是,匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性可能就会受到影响.C# 3.0中出现的Lambda表达式在 ...
- Lambda表达式和表达式树
在C# 2.0中,通过方法组转换和匿名方法,使委托的实现得到了极大的简化.但是,匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性可能就会受到影响.C# 3.0中出现的Lambda表达式在 ...
- C#复习笔记(4)--C#3:革新写代码的方式(Lambda表达式和表达式树)
Lambda表达式和表达式树 先放一张委托转换的进化图 看一看到lambda简化了委托的使用. lambda可以隐式的转换成委托或者表达式树.转换成委托的话如下面的代码: Func<string ...
- lambda表达式和表达式树(深入理解c#)
1.Lambda形式 1). Lambda表达式最冗长的形式: (显式类型的参数列表)=>{语句} 2). 大多数时候,都可以用一个表达式来表示主体,该表达式的值是Lambda的结果,在这些情况 ...
- 16.C#初见Lambda表达式及表达式树(九章9.1-9.3)
在说明Lambda相关知识前,我们需要了解Lambda表达式常用于LINQ,那么我们来聊下LINQ. LINQ的基本功能就是创建操作管道,以及这些操作需要的任何状态.这些操作表示了各种关于数据的逻辑: ...
- 深入学习C#匿名函数、委托、Lambda表达式、表达式树类型——Expression tree types
匿名函数 匿名函数(Anonymous Function)是表示“内联”方法定义的表达式.匿名函数本身及其内部没有值或者类型,但是可以转换为兼容的委托或者表达式树类型(了解详情).匿名函数转换的计算取 ...
随机推荐
- vue仿淘宝结账订单
<template> <div class="container"> <div class="checkout-title"& ...
- 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 ...
- uva-10041-水题
题意:有个人想找到个房子住,并且他经常去其他街道,输入n条街,给这个人选择一条街,使得他去其他街道的距离总和最小. 排序,双重for #include <string> #include& ...
- ODPS SQL <for 数据操作语言DML>
基本操作: 查询: SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference [WHERE where_co ...
- 修改git以往历史中所有commit的name和email
当换了新的电脑设备或者在 homestead 中使用 git 的时候:如果忘了 git config 设置用户名和邮箱:这样当 git commit 的时候就会使用设备名作为 git 用户名:或者我们 ...
- Linux网络编程学习计划
由于网络编程是很重要的一块,自己这一块也比较欠缺,只知道一些皮毛,从今天开始系统学习<Linux网络编程>一书,全书分为十四个章节: 第一章 概论 P1-16 第二章 UNIX ...
- LAMP架构
LAMP(linux,apache,mysql,php)是linux系统下常用的网站架构模型,用来运行PHP网站.(这得apache是httpd服务),这些服务可以安装同意主机上,也可以安装不同主机上 ...
- 十一、Composite 组合模式
原理: 代码清单 Entity public abstract class Entry { public abstract String getName(); public abstract int ...
- day37 异步回调和协程
异步回调 """ 异步任务使用场景 爬虫 1.从目标站点下载网页数据 本质就是HTML格式字符串 2.用re从字符串中提取出你需要的数据 ""&quo ...
- 关于C语言头文件写法的探讨
我不是软件工程出身,对于这方面一直处于探索阶段. 目前按照这样的习惯吧. 除主函数所在的文件以外,为每一个源文件配置一个头文件. 头文件里面不能写变量的申明和定义.头文件里面只写 #define,st ...