在C#中动态更改if语句的条件

我正在研究一种算法,其目的是创建一个特定事件发生的日期集合(这样我可以在MonthCalendar控件上加粗它们,或以其他方式显示它们)。

现在,对于可以用常规函数描述的简单时间间隔(例如,如果事件发生在每周一或每10天),这不是问题。

当我有一个不规则事件的事件时(例如,如果事件发生在每个星期五,如果该月的第一天是星期二和那种事件),则会出现真正的问题。

由于我无法预测该条件的格式,甚至无法预测需要满足的条件数量,因此我需要找到一种方法来了解如何在运行时更改相应if语句中的条件。

事件的定义存储在SQL数据库中。 现在我的想法是使用List,其中每个元素都是一个条件,然后将它们传递给适当的if语句(如果有多个语句)或将它们连接成一个字符串并传递给相应的if语句。

这种方法是否可行,我将如何做,或者我需要找到另一种方式,在这种情况下,请给我一个建议。

谢谢

您可以使用generics委托Predicate 。 (参见MSDN上的谓词(T)代表 )

Predicate将返回布尔值, IConditionParemeters抽象出一组条件参数,委托自身封装了一个返回值计算的逻辑。

 public class SimpleConditionParameters : IConditionParameters { public int XValue { get; set; } } public class ComplexConditionParameters : IConditionParameters { public int XValue { get; set; } public int YValue { get; set; } public bool SomeFlag { get; set; } } var conditions = new List>(); Predicate simpleCondition = (p) => { return p.XValue > 0; }; Predicate complexCondition = (p) => { return p.SomeFlag && p.XValue > 0 && p.YValue < 0; }; conditions.Add(simpleCondition); conditions.Add(complexCondition); 

另一种可能性是使用CodeDom在运行时动态生成代码,如下所示:

 public class DynamicIfStatementEvaluator { public bool EvaluateBools() { // Create a new instance of the C# compiler //from http://mattephraim.com/blog/2009/01/02/treating-c-like-a-scripting-language/ CSharpCodeProvider compiler = new CSharpCodeProvider(); // Create some parameters for the compiler CompilerParameters parms = new CompilerParameters { GenerateExecutable = false, GenerateInMemory = true }; parms.ReferencedAssemblies.Add("System.dll"); // Try to compile the string into an assembly CompilerResults results = compiler.CompileAssemblyFromSource(parms, new string[] {@"using System; class BoolEvaluator { public bool EvalBoolean() { return " + InsertBooleanStringHere! + @"; } }"}); if (results.Errors.Count == 0) { object myClass = results.CompiledAssembly.CreateInstance("BoolEvaluator"); if (myClass != null) { object boolReturn = myClass.GetType(). GetMethod("EvalBoolean"). Invoke(myClass, null); return Convert.ToBoolean(boolReturn); } } else { foreach (object error in results.Errors) { MessageBox.Show(error.ToString()); } } return false; } } 

添加using语句以使用System.CodeDom.Compiler;

您可能有不同类型的事件,例如DailyEventWeeklyEventMonthlyEVent等,所有这些事件都实现了一个给定的接口,该接口有一个名为CanFire (或类似的东西)的方法,另一个名为Execute

这将允许您创建各种类型的事件,每个事件都将实现它自己的逻辑,该逻辑决定是否需要触发它。

这将允许您创建一个列表并迭代事件,如果CanFire产生true,则调用Execute 。 这将允许您使每个事件类型具有自己的触发和执行逻辑。

那么你可以这样做:

 public abstract class Condition { public abstract bool ConditionMet(params[] parameters); } public class DateTimeCondition : Condition { public override bool ConditionMet(params[] parameters) { // check condition against DateTime values available inside parameters } } public class MoreThen10: Condition { public override bool ConditionMet(params[] parameters) { // check condition against numeric values more then 10 } } ... // and so on 

在你可以拥有somwhere全局条件集合之后:

 List conditions = new List() {new DateTimeCondition(), new MoreThen10Condition(),...}; 

当你要检查是否满足所有条件时,可以做到

 conditions.All(condition=>condition.ConditionMet(..parameters of if...)); 

当然,这只是基本的想法,草图,没有具体的实现,你可以复制/粘贴。