如何创建具有表达式作为参数的通用表达式
ASP.Net MVC中有一个DisplayNameFor(x=>x.Title)
帮助器。 我想在行为中实现类似的东西。
我想有一个方法接受基于User
类( u=>u.Birthdate
或u => u.Name)的表达式,一个操作数(Greater,Less,Equal)和一个像DateTime.Now
这样的值并返回一个表达式u=>u.Birthdate > DateTime.Now
我知道我必须手工构建结果表达式。 我无法包裹的是传递和处理属性表达。
编辑:
我想调用一个类似的方法
GetFilterPredicate(u=>u.Birthdate,FilterOps.GreaterThan,DateTime.Parse("01.01.2013")
或
GetFilterPredicate(u=>u.SomeIntProperty,FilterOps.Equals,2)
更新:我创建了一个包含此问题解决方案的repo以及一个集合属性过滤https://github.com/Alexander-Taran/Lambda-Magic-Filters
这满足了您的需求吗?
[TestClass] public class UnitTest1 { public Expression> GetFilterPredicate(Expression> selector, FilterOps operand, R value) { var parameter = selector.Parameters[0]; var left = selector.Body; var right = Expression.Constant(value); var binaryExpression = Expression.MakeBinary(operand.ToExpressionType(), left, right); return Expression.Lambda>(binaryExpression, parameter); } [TestMethod] public void TestMethod1() { var p1 = this.GetFilterPredicate((User u) => u.Birthday.TimeOfDay.Hours, FilterOps.LessThan, 12); var p2 = this.GetFilterPredicate((User u) => u.Size, FilterOps.Equal, 180); var user = new User() { Birthday = new DateTime(2000, 1, 1), Size = 180 }; Assert.IsTrue(p1.Compile()(user)); Assert.IsTrue(p2.Compile()(user)); } } public enum FilterOps { GreaterThan, LessThan, Equal } public static class MyExtensions { public static ExpressionType ToExpressionType(this FilterOps operand) { switch (operand) { case FilterOps.GreaterThan: return ExpressionType.GreaterThan; case FilterOps.LessThan: return ExpressionType.LessThan; case FilterOps.Equal: return ExpressionType.Equal; default: throw new NotSupportedException(); } } } public class User { public DateTime Birthday { get; set; } public int Size { get; set; } }
我相信这就是你的目标。
public Func MyMethod(Expression> func, ComparisonPredicate op, TProperty value) { } public enum ComparisonPredicate { Equal, Unequal, LessThan, LessThanOrEqualTo, GreaterThan, GreaterThanOrEqualTo }
像这样的东西:
Expression> GenerateAssignExpression (Expression> getExpression, TProperty Value) { var getExpressionBody = getExpression.Body as MemberExpression; if (getExpressionBody == null) { throw new Exception("getExpressionBody is not MemberExpression: " + getExpression.Body); } var objectParameter = (ParameterExpression)getExpression.Parameters[0]; ConstantExpression constant = Expression.Constant(Value, typeof(TProperty)); var expAssign = Expression.Assign(e.Body, constant); return Expression.Lambda>(expAssign, objectParameter, valueParameter); }
下面的方法将生成一个具有布尔返回值的二进制表达式
Expression> GenerateAssignExpression( Expression> expression, ExpressionType op, TProperty Value) { return Expression.Lambda>( Expression.MakeBinary(op, expression, Expression.Constant(Value)), getExpression.Parameters[0]); }
如果你想要一个generics返回类型只需将Predicate
更改为Func
(你需要替换’Predicate’的两个出现
上述就是C#学习教程:如何创建具有表达式作为参数的通用表达式分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1009237.html