C# 有没有办法在c中参数化运算符#

C# 有没有办法在c中参数化运算符#,c#,generics,C#,Generics,假设我有两个处理程序递增单击和递减单击,这两个处理程序调用公共方法 实际上,我的方法可能要复杂得多,我希望避免使用类似if的语法 if (operator == "+") { return value = value + step } else { return value = value - step } 然后做一些更一般的事情,像这样 increment(value, operator, step) { return value = value <ope

假设我有两个处理程序递增单击和递减单击,这两个处理程序调用公共方法

实际上,我的方法可能要复杂得多,我希望避免使用类似if的语法

if (operator == "+") {
     return value = value + step
}
else {
     return value = value - step
}
然后做一些更一般的事情,像这样

increment(value, operator, step) {
     return value = value <operator> step
}
增量(值、运算符、步长){
返回值=值步
}

这可能吗?

不,您只能参数化变量和泛型化类型。

您可以制作一个
字典,并使用运算符的实现进行设置,如下所示:

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

您甚至可以通过
Linq.Expressions
中的一些“魔法”来实现这一点:您可以通过编程方式定义lambda,并将它们编译成
Func

,而不是使用C中定义的预建lambda,我认为这不是更好的选择,但这是一个好选择

int sign = (operator == "+" ? 1 : -1);
retrun value +sign*value;

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

public delegate T Operation<T>(T arg, T step);
在要一般处理逻辑的类中,可以使用类似的代码:

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增量(Foo值、字符串@运算符、Foo步骤)
{
操作=null;
开关(@操作员)
{
格“+”:
操作=(v,s)=>v+s;
打破
案例“-”:
操作=(v,s)=>v-s;
打破
...
}
if(操作!=null)
{
返回操作(值、步长);
}
其他的
{
抛出新的NotSupportedException(
“运算符”“+@运算符”“不受支持”);
}
}
}
为了清晰起见,您可以使用.NET中支持这些操作的任何基元类型(
int
double
long
)来代替我使用的
Foo
类 您可以使用内置的
Func


我建议对运算符使用枚举而不是字符串(
+
-
,…),因为字符串将允许传递无效值。

您可以使用枚举。如果
枚举
后面有
开关,则仍然需要
开关。在调用端,是“运算符”编译时已知的值?第一个语法有什么问题?@NielsKeurentjes,当然,但它将只在函数上处理一次以供永久使用。虽然我喜欢这个解决方案,但它实际上并不是对实际问题的答案-您仍在进行运行时解析,因此本质上它只是一个重写的
switch
语句y、 创造力的荣誉,+1:)这回答了我的问题,虽然它很重:)呵呵,这个“?”的错误导致了这个后续:我将在这个答案中更正它。
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");
         }
    }
}