在C#中是否需要枚举开关上的默认情况?

mir*_*zus 27 .net c# enums switch-statement

我见过与C++有关的帖子,但我特地要求C#.NET(4.0+).

在以下示例中是否需要默认情况?

public enum MyEnum : int
{
    First,
    Second
}

public class MyClass
{

    public void MyMethod(MyEnum myEnum)
    {
        switch (myEnum)
        {
            case MyEnum.First: /* ... */ break;
            case MyEnum.Second: /* ... */ break;

            default: /* IS THIS NECESSARY??? */ break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jar*_*Par 36

这是一个常见的误解,即.Net枚举值仅限于枚举中声明的值.实际上,虽然它们可以是枚举的基本类型范围内的任何值(int默认情况下).例如,以下内容完全合法

MyMethod((MyEnum)42);
Run Code Online (Sandbox Code Playgroud)

此代码将在没有警告的情况下编译,并且不会打开任何case标签.

现在,您的代码是否选择处理此类方案是一项策略决策.这不是必要的,但我肯定会建议有一个.我宁愿一个添加default到每个switch上枚举我写专门为这个场景有以下模式

switch (value) { 
  ...
  default: 
    Debug.Fail(String.Format("Illegal enum value {0}", value));
    FailFast();  // Evil value, fail quickly 
}
Run Code Online (Sandbox Code Playgroud)

  • 我想补充说Jared的答案是,如果你有一个基于一个字节的枚举,并且你的交换机中有*所有256个案例*,那么编译器仍然可能需要一个默认情况下进行明确的分配检查.有关详细信息,请参阅http://blogs.msdn.com/b/ericlippert/archive/2009/08/13/four-switch-oddities.aspx. (6认同)
  • 另一种情况是,如果枚举是在不同的程序集中定义的。在这种情况下,有人可能会向枚举添加一个字段,然后针对新版本运行您的代码,而无需重新编译。编译器坚持生成对此类事情具有鲁棒性的代码。 (2认同)

Jef*_*nal 13

这不是绝对必要的,但有人可能会传入您的枚举未涵盖的值(因为枚举实际上并不限制允许的参数值的范围).

我通常会添加一个默认值,throw如果指定的值是意外的.


Joh*_*lph 6

这在技术上是不必要的,但是因为您可以轻松地将MyEnums基础类型(通常为int)的值转换为实例MyEnum.因此,最好添加一个带有a的默认语句Debug.Assert().


Phi*_*rie 5

这不是必需的,而是良好的做法,因为有人可能会在以后引入新的枚举.例如,抛出一个异常,指示未处理"未知"枚举.