Dynamically changing conditions of an if statement in C#

不打扰是莪最后的温柔 提交于 2019-12-06 16:46:02

问题


I'm working on an algorithm whose purpose is to create a collection of dates on which a certain event occurs (so that I can bold them on a MonthCalendar control, or display them in some other way).

Now, for simple time intervals that can be described with regular functions (for instance if the event occurs every Monday or every 10 days) this is not a problem.

The real problem occurs when I have an event with irregular occurrences (for instance if event occurs every Friday if the first day of the month is Tuesday and that kind of events).

Since I can't predict the format of that condition's, or even the number of conditions that need to be met, I need to find a way on how to change the condition(s) inside the appropriate if statement during run-time.

The definitions of events are stored in a SQL database. Now my idea is to use a List whose every element would be one condition, and then pass them to appropriate if statements (if there are multiple statements) or join them into one string and pass to the appropriate if statement.

Is this approach possible, and how would I do it, or do I need to find another way, in which case please give me a suggestion.

Thanks


回答1:


You can use generic delegate Predicate<T>. (See Predicate(T) Delegate on MSDN)

Predicate<IConditionParameters> will return boolean value, IConditionParemeters abstracts a set of condition parameters and delegate itself encapsulates a logic for return value computation.

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);



回答2:


Another possibility would be to use CodeDom to dynamically generate code at runtime, like this:

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

Add a using statement for using System.CodeDom.Compiler;




回答3:


You could, maybe, have different types of events such as DailyEvent, WeeklyEvent, MonthlyEVent, etc, all of which implement a given interface which has a method named CanFire (or something like that) and another named Execute.

This will allow you to create various types of events, each of which will implement it's own logic which decides if it needs to be fired or not.

This will allow you to create a list and just iterate over the events and if CanFire yields true, then, call Execute. This will allow you to have each event type with have its own firing and execution logic.




回答4:


Well you can do something like this:

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 

after you can have somwhere global collection of conditions:

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

and when you're going to check if all conditions met, can do

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

Naturally this is just basic idea, a sketchup, no concrete implementation that you can copy/paste.



来源:https://stackoverflow.com/questions/12278251/dynamically-changing-conditions-of-an-if-statement-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!