繁体   English   中英

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

[英]Dynamically changing conditions of an if statement in C#

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

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

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

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

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

这种方法可行吗?我将如何做?还是需要寻找另一种方法,在这种情况下,请给我一个建议。

谢谢

您可以使用通用委托Predicate<T> (请参阅MSDN上的Predicate(T)代表

Predicate<IConditionParameters>将返回布尔值, 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<IConditionParameters>>();
Predicate<SimpleConditionParameters> simpleCondition = (p) => 
{
   return p.XValue > 0;
};

Predicate<ComplexConditionParameters> 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;
    }        
}

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

您可能拥有不同类型的事件,例如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 

在获得全球各地条件后:

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

当您要检查是否满足所有条件时,

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

自然,这只是一个基本概念,一个草图,没有可以复制/粘贴的具体实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM