我正在尝试为我正在使用基于这篇文章的表达式树的规则引擎构建一些附加功能 - How to implement a rule engine?
我的规则之一是,如果发现该属性类型是 DateTime,则向该属性添加分钟。例如,我可以使用“DOB + 60”或“DOB - 180”。
我当前的代码正在为此工作:
var expression = new string[] {"DOB", "+", "60"};
var property = Expression.Property(param, expression[0]);
var method = typeof(T).GetProperty(expression[0]).PropertyType.GetMethod("AddMinutes");
/* If we have a AddMinutes method then assume type is of DateTime */
if (method != null)
{
var tParam = method.GetParameters()[0].ParameterType;
/* Calculate if we're adding or subtracting minutes */
var convertedNo = expression[1] == "-" ? int.Parse(expression[2]) * -1 : int.Parse(expression[2]);
var number = Expression.Constant(Convert.ChangeType(convertedNo, tParam));
var exp = Expression.Call(property, method, number);
/* Allows for left property < DOB.AddMinutes(60) */
return Expression.MakeBinary(ExpressionType.LessThan, left, exp);
}
我遇到的问题是 DOB 属性可能设置为 DateTime.Min,这样当我的表达式计算“DOB - 180”时,在这种情况下会抛出越界异常,因为它试图减去 180 DateTime.Min 的分钟数。
我试图通过使用 Expression.IfThenElse 来解决这个问题,这样如果 DateTime 属性等于 DateTime.Min,则不进行计算而只对 DateTime.Min 求值。
我更新后的代码如下所示:
var expression = new string[] {"DOB", "-", "180"};
var property = Expression.Property(param, expression[0]);
var method = typeof(T).GetProperty(expression[0]).PropertyType.GetMethod("AddMinutes");
/* If we have a AddMinutes method then assume type is of DateTime */
if (method != null)
{
var tParam = method.GetParameters()[0].ParameterType;
/* Calculate if we're adding or subtracting minutes */
var convertedNo = expression[1] == "-" ? int.Parse(expression[2]) * -1 : int.Parse(expression[2]);
var number = Expression.Constant(Convert.ChangeType(convertedNo, tParam));
var exp = Expression.Call(property, method, number);
var minDate = Expression.Constant(Convert.ChangeType(DateTime.MinValue, typeof(DateTime)));
var minDateCheck = Expression.MakeBinary(ExpressionType.Equal, property, minDate);
var minDateExp = Expression.IfThenElse(minDateCheck, minDate, exp);
/* To allow for left property < DOB == DateTime.Min ? DateTime.Min : DOB.AddMinutes(60) */
return Expression.MakeBinary(ExpressionType.LessThan, left, minDateExp); // Exception thrown here
}
不幸的是,这会引发异常 - 无法将 DateTime 与返回类型 void 进行比较。我尝试了几种变体,但总是得到相同的异常。
谁能告诉我如何构造一个能够执行此逻辑的表达式?
最佳答案
Expression.IfThenElse
等效于 C# - 好吧,if
语句,而您需要的是等效于 C# ?: 的表达式(又名 条件)运算符,即 ConditionalExpression
由 Expression.Condition
制作方法。
很快,替换
var minDateExp = Expression.IfThenElse(minDateCheck, minDate, exp);
与
var minDateExp = Expression.Condition(minDateCheck, minDate, exp);
你就完成了。
关于c# - 使用 Linq 表达式返回默认 DateTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38489602/