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
用于left
和right
,因此结果也将是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#从asp.net MVC中的枚举绑定下拉列表[重复]
如何在 C# 中为枚举值添加描述以与 ASP.NET MVC 中的下拉列表一起使用? [复制]