0

I need a function that will take operands/operators as parameters and provide the evaluation result. The problem that I am facing is how to elegantly parse an operator.

Sample code is as below

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

I can put operators in enum (or extendable enum) and use strategy pattern to remove the switch case. The issue remains, I cannot parse operators. example

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

Please suggest how to refactor above code (Evaluator function) elegantly.

Itay Grudev
  • 7,055
  • 4
  • 54
  • 86
Tilak
  • 30,108
  • 19
  • 83
  • 131

2 Answers2

1

I think you may be looking for something like this:

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

You can use it like this:

var op = ParseOperation("<");
Console.WriteLine(op(1, 2)); // true
ChaosPandion
  • 77,506
  • 18
  • 119
  • 157
  • very close, and neat. I am looking something similar, but i also want to remove switch-case to add few more operators later. – Tilak Apr 29 '12 at 04:04
1

The switch statement is the simplest implementation of a chain of responsibility pattern, the purpose of which is to route your problem to the correct handler. The classic GoF implementation is the Linked List. Wikipedia has a good article, as does NetObjectives.

Another good implementation for you problem is the Registry implementation. This works here because the rule is always the same -- match a given key to an operation. Fill in this abstraction, backing it with a dictionary. Pre-load the dictionary with the operations you know about.

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, I'd prefer to see a new class instead of Func, but perhaps that is just me.

tallseth
  • 3,635
  • 1
  • 23
  • 24
  • dictinary implementation seems clean to me. regarding Func, you are right, a new Class is better. – Tilak Apr 30 '12 at 03:04