Dynamically changing conditions of an if statement in C#

蹲街弑〆低调 提交于 2019-12-04 21:00:49

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

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;

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.

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.

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