我需要一个将操作数/运算符作为参数并提供评估结果的函数。 我面临的问题是如何优雅地解析操作符。
示例代码如下
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;
}
我可以将运算符放在枚举(或可扩展的枚举)中,并使用策略模式来删除switch case。 问题仍然存在,我无法解析运营商。 示例
op1="<";
var operation = Operation.Parse(op1);
var result = operand1 <-- operation should come here --> operand2.
请建议如何优雅地重构上面的代码(Evaluator功能)。
答案 0 :(得分: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
答案 1 :(得分:1)
switch语句是责任链模式的最简单实现,其目的是将问题路由到正确的处理程序。经典的GoF实现是链接列表。 Wikipedia有一篇好文章,NetObjectives也是如此。
另一个很好的实现问题是Registry实现。这可以在这里工作,因为规则总是相同的 - 将给定的键与操作匹配。填写这个抽象,用字典支持它。使用您了解的操作预加载字典。
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,但也许这只是我。