0

オペランド/演算子をパラメーターとして受け取り、評価結果を提供する関数が必要です。私が直面している問題は、演算子をエレガントに解析する方法です。

サンプルコードは以下の通り

internal static bool Evaluator(double operand1, double operand2, string operation)
{
    bool evaluation = false;
    switch (operation)
    {
        case "<":
            evaluation = operand1 < operand2;
            break;

        case ">":
            evaluation = operand1 > operand2;
            break;

        case "<=":
            evaluation = operand1 <= operand2;
            break;

        default:
            break;
    }

    return evaluation;
}

演算子を列挙型 (または拡張可能な列挙型) に配置し、戦略パターンを使用してスイッチ ケースを削除できます。問題は残ります。演算子を解析できません。例

     op1="<";
     var operation = Operation.Parse(op1);
     var result = operand1 <--  operation should come here --> operand2.

上記のコード (エバリュエーター関数) をエレガントにリファクタリングする方法を提案してください。

4

2 に答える 2

1

私はあなたがこのようなものを探しているかもしれないと思います:

public static Func<double, double, bool> ParseOperation(string operation)
{
    switch (operation)
    {
        case "<":
            return (x, y) => x < y;

        case ">":
            return (x, y) => x > y;

        case "<=":
            return (x, y) => x <= y;

        default:
            throw new Exception();
    }
}

次のように使用できます。

var op = ParseOperation("<");
Console.WriteLine(op(1, 2)); // true
于 2012-04-29T03:50:36.900 に答える
1

switch ステートメントは、一連の責任パターンの最も単純な実装であり、その目的は、問題を正しいハンドラーにルーティングすることです。古典的な GoF の実装は Linked List です。 ウィキペディアには良い記事があり、NetObjectivesも同様です。

問題に対するもう 1 つの適切な実装は、レジストリの実装です。これは、ルールが常に同じであるため、ここで機能します。特定のキーを操作に一致させます。この抽象化を入力し、辞書で裏付けます。知っている操作でディクショナリをプリロードします。

public abstract class OperationRegistry
{
   public abstract void RegisterOperation(string symbol, Func<double, double, bool> operation);
   public abstract Func<double, double, bool> GetOperation(string symbol);
}

FWIW、私は Func の代わりに新しいクラスを見たいと思っていますが、おそらくそれは私だけです。

于 2012-04-29T04:45:06.680 に答える