【问题标题】:In C# is default case necessary on a switch on an enum?在 C# 中,枚举开关是否需要默认情况?
【发布时间】:2010-12-17 16:45:14
【问题描述】:

我看过relating to 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;
        }
    }
}

【问题讨论】:

标签: c# .net enums switch-statement


【解决方案1】:

.Net 枚举值仅限于枚举中声明的值是一种常见的误解。实际上,尽管它们可以是枚举基本类型范围内的任何值(默认为int)。例如以下是完全合法的

MyMethod((MyEnum)42);

此代码将在没有警告的情况下编译,并且不会命中您的任何case 标签。

现在,您的代码是否选择处理这种类型的场景是一个政策决定。这不是必要的,但我肯定推荐拥有一个。我更喜欢在枚举上的每个switch 中添加一个default,我专门为此场景编写了以下模式

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

【讨论】:

  • 我会在 Jared 的回答中补充一点,如果您有一个基于字节的枚举,并且您的开关中有 所有 256 个案例,即使这样编译器仍然可能需要一个用于明确分配检查的默认情况。详情请见blogs.msdn.com/b/ericlippert/archive/2009/08/13/…
  • 另一个起作用的情况是枚举是在不同的程序集中定义的。在这种情况下,有人可能会在枚举中添加一个字段,然后在不重新编译的情况下针对新版本运行您的代码。编译器坚持生成对这种事情健壮的代码。
【解决方案2】:

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

如果指定的值意外,我通常会添加默认值和throw

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      这不是必需的,但是很好的做法,因为稍后有人可能会引入新的枚举。例如抛出一个异常,表示未处理“未知”枚举。

      【讨论】:

        【解决方案5】:

        不,不需要默认大小写。

        【讨论】:

          【解决方案6】:

          从纯代码的角度来看,不需要default 案例。这完全取决于您的逻辑要求。

          【讨论】:

            【解决方案7】:

            如果您将其转换为枚举未定义值(不会抛出异常),则需要它,如果您向枚举添加更多值。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-06-16
              • 1970-01-01
              • 1970-01-01
              • 2021-09-22
              • 2018-09-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多