c# 扩展方法奇思妙用基础篇九:Expression 扩展
2011-09-15 17:18 鹤冲天 阅读(26794) 评论(17) 编辑 收藏 举报.net 中创建 Expression Trees 最简单的方式是使用 lambda 表达式:
1 2 |
Expression<Func<Person, bool>> exp = p => p.Name.Contains("ldp") && p.Birthday.Value.Year > 1990; |
其中 Person 类定义如下:
1 2 3 4 |
public class Person { public string Name { get; set; } public DateTime? Birthday { get; set; } } |
但有些时候,要动态创建 Expression Trees,我们要用到 System.Linq.Expressions 命名空间中的 Expression 类。
使用 Expression 类 中的静态方法,前面的 Expression Trees 可如下创建:
1 2 3 4 5 6 7 8 9 10 |
var parameter = Expression.Parameter(typeof(Person), "p"); var left = Expression.Call( Expression.Property(parameter, "Name"), typeof(string).GetMethod("Contains"), Expression.Constant("ldp")); var right = Expression.GreaterThan( Expression.Property(Expression.Property(Expression.Property(parameter, "Birthday"), "Value"), "Year"), Expression.Constant(1990)); var body = Expression.AndAlso(left, right); var lambda = Expression.Lambda<Func<Person, bool>>(body, parameter); |
你应该注意到第 7 行高亮部分,三个重复的 Expression.Property,显得非常臃肿,导致可读性也很差。
可以用下面几个扩展方法予以简化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public static class ExpressionExtensions { public static Expression AndAlso(this Expression left, Expression right) { return Expression.AndAlso(left, right); } public static Expression Call(this Expression instance, string methodName, params Expression[] arguments) { return Expression.Call(instance, instance.Type.GetMethod(methodName), arguments); } public static Expression Property(this Expression expression, string propertyName) { return Expression.Property(expression, propertyName); } public static Expression GreaterThan(this Expression left, Expression right) { return Expression.GreaterThan(left, right); } public static Expression<TDelegate> ToLambda<TDelegate>(this Expression body, params ParameterExpression[] parameters) { return Expression.Lambda<TDelegate>(body, parameters); } } |
这五个扩展方法相当简单,没什么技术含量。可以根据自己需要,添加更多的扩展方法。
前面的代码简化成:
1 2 3 4 |
var parameter = Expression.Parameter(typeof(Person), "p"); var left = parameter.Property("Name").Call("Contains", Expression.Constant("ldp")); var right = parameter.Property("Birthday").Property("Value").Property("Year").GreaterThan(Expression.Constant(1990)); var lambda = left.AndAlso(right).ToLambda<Func<Person, bool>>(parameter); |
是不是好多了。
简单编码,快乐生活!
《c#扩展方法奇思妙用》系统文章从 2009 年 08 月开始写起,到现在一共有了 24 篇,欢迎阅读:
-------------------
思想火花,照亮世界
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库