C#如何使用带开关的枚举

Posted

技术标签:

【中文标题】C#如何使用带开关的枚举【英文标题】:C# how to use enum with switch 【发布时间】:2013-02-14 16:18:11 【问题描述】:

我不知道如何将开关与枚举结合使用。你能告诉我我做错了什么,以及如何解决吗?我必须使用枚举来制作基本的计算器。

public enum Operator

    PLUS, MINUS, MULTIPLY, DIVIDE


public double Calculate(int left, int right, Operator op)


    int i = (int) op;

    switch(i)
    
        case 0:
        
            return left + right;
        

        case 1:
        
            return left - right;
        

        case 2:
         
            return left * right;
        

        case 3:
        
            return left / right;
        

        default:
        
            return 0.0;
        
    

最终结果应该是这样的:

Console.WriteLine("The sum of 5 and 5 is " + Calculate(5, 5, PLUS))
Output: The sum of 5 and 5 is 10

你们能告诉我我是怎么搞砸的吗?

【问题讨论】:

【参考方案1】:

你不需要转换它

switch(op)

     case Operator.PLUS:
     
        // your code 
        // for plus operator
        break;
     
     case Operator.MULTIPLY:
     
        // your code 
        // for MULTIPLY operator
        break;
     
     default: break;

顺便说一下,用括号

【讨论】:

@J.Starkl 嗯,这是一个见仁见智的问题,我认为 :-) @StephanBauer:是的,它是:-) 我自己更像是一个缩进的人 =) 奇怪的是,这是我唯一没有戴上大括号的东西。去图吧! 如果你曾经引入一个新的变量用于单个案例,你当然需要使用括号。那时我的强迫症开始了,我需要通过添加括号来使所有案例看起来都一样。 (说真的,我在 switch 语句中使用方括号,因为我在其他任何地方都将它们用于块。) 是的,但是如果你在任何地方都使用它们 - 没有陷阱 - 一致的代码 - 提高了可读性 - 更简单的维护/扩展 - 最佳实践(习惯它们)【参考方案2】:

由于 C# 8.0 为枚举引入了新的 switch 表达式,您可以更优雅地做到这一点:

public double Calculate(int left, int right, Operator op) =>
            op switch 
        
            Operator.PLUS => left + right,
            Operator.MINUS => left - right,
            Operator.MULTIPLY => left * right,
            Operator.DIVIDE => left / right,
            _    =>  0
        

参考。 https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8

【讨论】:

任何减少花括号需求的语法糖都是好的。 请将其中一个被分割的值转换成double,不要混淆新人,传播错误代码。【参考方案3】:

已经给出了正确的答案,但是这里是更好的方法(比切换):

private Dictionary<Operator, Func<int, int, double>> operators =
    new Dictionary<Operator, Func<int, int, double>>
    
         Operator.PLUS, ( a, b ) => a + b ,
         Operator.MINUS, ( a, b ) => a - b ,
         Operator.MULTIPLY, ( a, b ) => a * b ,
         Operator.DIVIDE ( a, b ) => (double)a / b ,
    ;

public double Calculate( int left, int right, Operator op )

    return operators.ContainsKey( op ) ? operators[ op ]( left, right ) : 0.0;

【讨论】:

我认为这是一个使用 var 来声明变量的例子! Var 不能在方法体之外使用。 1.配置和逻辑分离:你的代码变得简短易读。您的配置读起来像一张桌子,这也很简单。 2. 与switch不同,Dictionary内部使用哈希表进行快速查找,当有很多情况时,这变得很重要。有时程序员将最常用的项目放在切换的末尾,并且会出现性能问题。 3. 一旦配置从代码中提取出来,现在你可以做出很多很棒的事情: A.将其从代码移动到外部源,例如配置文件或数据库。 B. 在程序执行时根据您的需要动态修改配置。 C. 创建一个插件系统,让你的配置被模块扩展。 D. 尽管 Dictionary 已经有助于更快地搜索关键字,但您可以通过自定义查找操作的方式使其变得更好。有一次我为 switch 实现了这样的替换,它在程序执行期间累积了 case 使用统计信息,并定期重新排列 case 列表,以便最受欢迎的一个成为第一个。 我希望看到一个可靠的证据表明字典查找比“使用枚举切换”更快。【参考方案4】:

您不应该转换为整数。对于除法,您需要先将 left 转换为 double,否则您将进行整数除法。

public enum Operator

    PLUS, MINUS, MULTIPLY, DIVIDE


public double Calculate(int left, int right, Operator op)

    double sum = 0.0;

    switch(op)
    
       case Operator.PLUS:
       sum = left + right;
       return sum;

       case Operator.MINUS:
       sum = left - right;
       return sum;

       case Operator.MULTIPLY:
       sum = left * right;
       return sum;

       case Operator.DIVIDE:
       sum = (double)left / right;
       return sum;

       default:
       return sum;
   

   return sum;

【讨论】:

【参考方案5】:

只是不要转换为 int

 switch(operator)
    
       case Operator.Plus:
       //todo

【讨论】:

【参考方案6】:

无需转换。您可以在开关内的枚举上应用条件。像这样,

public enum Operator
 
    PLUS,
    MINUS,
    MULTIPLY,
    DIVIDE


public double Calculate(int left, int right, Operator op)

    switch (op)
    
        case Operator.PLUS: return left + right; 
        case Operator.MINUS: return left - right; 
        case Operator.MULTIPLY: return left * right;
        case Operator.DIVIDE: return left / right;
        default: return 0.0; 
    

然后,这样称呼它:

Console.WriteLine("The sum of 5 and 5 is " + Calculate(5, 5, Operator.PLUS));

【讨论】:

这个答案完美地说明了打破约定并使用 1)从函数提前返回和 2)将案例与代码放在同一行的正确时间。【参考方案7】:
 public enum Operator
    
        PLUS, MINUS, MULTIPLY, DIVIDE
    

    public class Calc
    
        public void Calculate(int left, int right, Operator op)
        

            switch (op)
            
                case Operator.DIVIDE:
                    //Divide
                    break;
                case Operator.MINUS:
                    //Minus
                    break;
                case Operator.MULTIPLY:
                    //...
                    break;
                case Operator.PLUS:
                    //;;
                    break;
                default:
                    throw new InvalidOperationException("Couldn't process operation: " + op);
            
        
    

【讨论】:

【参考方案8】:

如果您不想在每种情况下都使用 return 语句,请尝试以下操作:

Calculate(int left, int right, Operator op)

   int result = 0;
   switch(op)
   
        case Operator.PLUS:
        
            result = left + right;;  
        
        break;
        ....
   

   return result;

【讨论】:

不清楚这如何使代码更具可读性,而不是强制项目本地样式约定。 OP 的示例代码块是提前返回如何使代码更具可读性的经典示例。【参考方案9】:

其他所有答案都是正确的,但你还需要正确调用你的方法:

Calculate(5, 5, Operator.PLUS))

由于您将int 用于leftright,因此结果也将是int (3/2 will result in 1)。您可以在计算结果之前转换为double,或者修改您的参数以接受double

【讨论】:

嗯..是的,有点... :-D【参考方案10】:

两件事。首先,您需要在测试中限定枚举引用 - 而不是“PLUS”,它应该是“Operator.PLUS”。其次,如果您在 switch 语句中使用枚举成员名称而不是它们的整数值,则此代码将更具可读性。我已经更新了你的代码:

public enum Operator

    PLUS, MINUS, MULTIPLY, DIVIDE


public static double Calculate(int left, int right, Operator op)

    switch (op)
    
        default:
        case Operator.PLUS:
            return left + right;

        case Operator.MINUS:
            return left - right;

        case Operator.MULTIPLY:
            return left * right;

        case Operator.DIVIDE:
            return left / right;
    

调用它:

Console.WriteLine("The sum of 5 and 5 is " + Calculate(5, 5, Operator.PLUS));

【讨论】:

【参考方案11】:

您的代码很好。如果您不确定如何使用计算功能,请尝试

Calculate(5,5,(Operator)0); //this will add 5,5
Calculate(5,5,Operator.PLUS);// alternate

默认枚举值从 0 开始,并为以下元素增加 1,直到您分配不同的值。你也可以这样做:

public enum OperatorPLUS=21,MINUS=345,MULTIPLY=98,DIVIDE=100;

【讨论】:

以上是关于C#如何使用带开关的枚举的主要内容,如果未能解决你的问题,请参考以下文章

C#资源文件和C#枚举如何结合使用?

如何检测新值已添加到枚举中并且未在开关中处理

如何使用C#从asp.net MVC中的枚举绑定下拉列表[重复]

如何在 C# 中为枚举值添加描述以与 ASP.NET MVC 中的下拉列表一起使用? [复制]

如何使用 C# 从字符串数组制作类似枚举的 Unity 检查器下拉菜单?

如何将带有枚举的 VB.net 接口转换为 C#