见我这里最近的答案:Parsing "DateTime.Now"?
本质上讲,你可以很容易地利用诸如FLEE现有的库来解析表达式,并发出IL这些规则。如果你看看这些例子,你可以看到如何设置用户表达式的变量来利用。例如,您可以定义一个由某些输入变量(如HireDate
或EnrollmentDate
)组成的“规则”以及返回日期的用户表达式/谓词。如果您在链接的答案中公开DateTime
成员,那么用户也可以利用这些成员。
就像一个简单的例子,没有经过测试,但应该给你一个想法。
您可以设置一些自定义的功能,帮助,就像得到了一个月的第一天:
public static class CustomFunctions
{
public static DateTime GetFirstDayOfMonth(DateTime date)
{
return new DateTime(date.Year, date.Month, 1);
}
}
基本FLEE设置(你必须定制/调整必要)
ExpressionContext context = new ExpressionContext();
//Tell FLEE to expect a DateTime result; if the expression evaluates otherwise,
//throws an ExpressionCompileException when compiling the expression
context.Options.ResultType = typeof(DateTime);
//Instruct FLEE to expose the `DateTime` static members and have
//them accessible via "DateTime".
//This mimics the same exact C# syntax to access `DateTime.Now`
context.Imports.AddType(typeof(DateTime), "DateTime");
context.Imports.AddType(typeof(CustomFunctions));
//Expose your key variables like HireDate and EnrollmentDate
context.Variables["HireDate"] = GetHireDate(); //DateTime I suppose
context.Variables["EnrollmentDate"] = GetEnrollmentDate(); //DateTime I suppose
//Parse the expression, naturally the string would come from your data source
IGenericExpression<DateTime> expression = context.CompileGeneric<DateTime>(GetYourRule(), context);
DateTime date = expression.Evaluate();
那么你的规则可能看起来像:
string rule1 = "if(HireDate > EnrollmentDate, HireDate, EnrollmentDate)";
string rule2 = "HireDate.AddDays(90)";
string rule3 = "GetFirstDayOfMonth(EnrollmentDate.AddMonths(1))";
string rule4 = "GetFirstDayOfMonth(EnrollmentDate.AddMonths(if(EnrollmentDate.Day < 15, 1, 2)))";
可以FLEE可空类型的工作?让我们说,而不是构建一个需要两个DateTime参数的表达式,如果雇用日期未知,我需要能够将null传递给HireDate? – Aheho
@Aheho我_think_所以,但你最好避免使用它的各种隐式运算符并使用它的'.Value'属性。例如,如果'HireDate'是键入'DateTime?',而不是简单地检查'if(HireDate> DateTime.Now)'你可能想'if(HireDate.Value> DateTime.Now)''。你也可以避免可空可以有一个单独的布尔标志暴露“HasHireDate”,如果这是'false',那么'HireDate'可能是过去的默认值或只是'new DateTime()' –