0

特定のイベントが発生する日付のコレクションを作成することを目的としたアルゴリズムに取り組んでいます(MonthCalendarコントロールで太字にしたり、他の方法で表示したりできるようにするため)。

現在、通常の関数で記述できる単純な時間間隔(たとえば、イベントが毎週月曜日または10日ごとに発生する場合)の場合、これは問題ではありません。

実際の問題は、不規則に発生するイベントがある場合に発生します(たとえば、月の最初の日が火曜日である場合に毎週金曜日にイベントが発生する場合、そのようなイベント)。

その条件の形式、または満たす必要のある条件の数さえも予測できないため、実行時に適切なifステートメント内で条件を変更する方法を見つける必要があります。

イベントの定義はSQLデータベースに保存されます。ここでの私の考えは、すべての要素が1つの条件になるリストを使用し、それらを適切なifステートメントに渡すか(複数のステートメントがある場合)、それらを1つの文字列に結合して、適切なifステートメントに渡すことです。

このアプローチは可能ですか、それをどのように行うのでしょうか、または別の方法を見つける必要がありますか?その場合は、提案をお願いします。

ありがとう

4

4 に答える 4

3

汎用デリゲートを使用できますPredicate<T>。( MSDN のPredicate(T) Delegateを参照してください)

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);
于 2012-09-05T09:26:30.003 に答える
2

もう 1 つの可能性は、次のように 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 ステートメントを追加します。

于 2013-09-17T15:34:26.007 に答える
0

おそらく、 、 、 などのさまざまなタイプのイベントを持つことができますDailyEventWeeklyEventこれらはすべて、 という名前のメソッド(またはそのようなもの) と別の名前MonthlyEVentのメソッドを持つ特定のインターフェイスを実装します。CanFireExecute

これにより、さまざまなタイプのイベントを作成できます。各イベントは、起動する必要があるかどうかを決定する独自のロジックを実装します。

これにより、リストを作成してイベントを反復処理し、CanFire結果が true の場合は を呼び出すことができますExecute。これにより、各イベント タイプに独自の起動および実行ロジックを持たせることができます。

于 2012-09-05T09:29:42.203 に答える
0

さて、あなたはこのようなことをすることができます:

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

当然、これは単なる基本的なアイデアであり、スケッチアップであり、コピー/貼り付けできる具体的な実装ではありません。

于 2012-09-05T09:30:06.763 に答える