4

Let's say I have 2 handlers increment_click and decrement_click which calls common method

In real my method can be much more complex and I'd like to avoid to use syntax like with if

if (operator == "+") {
     return value = value + step
}
else {
     return value = value - step
}

and do something more generic like this

increment(value, operator, step) {
     return value = value <operator> step
}

Is it somehow possible ?

4

4 回答 4

11

您可以使用Dictionary<string,Func<decimal,decimal,decimal>>运算符的实现创建并设置它,如下所示:

private static readonly IDictionary<string,Func<decimal,decimal,decimal>> ops = new Dictionary<string,Func<decimal,decimal,decimal>> {
    {"+", (a,b) => a + b}
,   {"-", (a,b) => a - b}
,   {"*", (a,b) => a * b}
,   {"/", (a,b) => a / b}
};

现在你可以这样做:

decimal Calculate(string op, decimal a, decimal b) {
    return ops[op](a, b);
}

你甚至可以用一些“魔法”来做这件事Linq.Expressions:而不是使用 C# 中定义的预构建 lambda,你可以以编程方式定义你的 lambda,并将它们编译成Func<T,T,T>.

于 2013-06-09T18:38:00.210 回答
2

我不确定您的整个用例是什么,但这似乎是雇用代表的合适场景。让我们从定义一个委托开始:

public delegate T Operation<T>(T arg, T step);

现在让我们假设你有一个带运算符的类:

public class Foo
{
    public static Foo operator + (Foo left, Foo right) { ... } 
    public static Foo operator + (Foo left, Foo right) { ... } 
}

在您想要通用处理逻辑的类中,您可以使用类似的代码:

public class Bar
{
    // The method you look for:
    public Foo Increment(Foo value, string @operator, Foo step)
    {
         Operation<Foo> operation = null;

         switch(@operator)
         {
             case "+":
                 operation = (v, s) => v + s;
                 break;
             case "-":
                 operation = (v, s) => v - s;
                 break;
             ...
         }

         if (operation != null)
         {
             return operation(value, step);
         }
         else
         {
             throw new NotSupportedException(
                 "Operator '" +  @operator "' is not supported");
         }
    }
}

代替Foo我为清楚起见使用的类,您可以使用 .NET 中支持这些操作的任何基本类型(intdoublelong等)。与其定义
自己的Operation<T>委托 (Func<T, T>
+-

于 2013-06-09T18:46:52.350 回答
2

我不认为这更好,但这是一个不错的选择

int sign = (operator == "+" ? 1 : -1);
retrun value +sign*value;
于 2013-06-09T18:39:43.627 回答
1

不,您只能对变量进行参数化,并对类型进行泛化。

于 2013-06-09T18:37:14.980 回答