假设我有2个处理程序increment_click和decrement_click调用常用方法
实际上我的方法可能要复杂得多,我想避免使用与if
类似的语法if (operator == "+") {
return value = value + step
}
else {
return value = value - step
}
并做一些像这样更通用的事情
increment(value, operator, step) {
return value = value <operator> step
}
有可能吗?
答案 0 :(得分: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
中的一些“魔法”来执行此操作:您可以通过编程方式定义lambdas,而不是使用C#中定义的预先建立的lambda,并将它们编译为Func<T,T,T>
。< / p>
答案 1 :(得分:2)
我认为这不是更好,但这是一个不错的选择
int sign = (operator == "+" ? 1 : -1);
retrun value +sign*value;
答案 2 :(得分: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中支持这些操作的任何基本类型(int
,double
,{{1等等)
您可以使用内置long
来代替定义自己的代理(例如Operation<T>
。)
我建议为运算符(Func<T, T>
,+
,...)使用枚举而不是字符串,因为字符串将允许传递无效值。
答案 3 :(得分:1)
不,您只能参数化变量,并对类型进行泛化。