c# - 当开关不处理一个或多个枚举值时,我可能会出现 C# 编译时错误吗?

标签 c# .net compile-time

假设我有一个 switch 来控制一些包含枚举的变量:

SomeEnum variable;
switch( variable ) {
   case Option1:
      Magic1;
      break;
   case Option2:
      Magic2;
      break;
   default:
      throw new InvalidOperationException();
}

而且我知道 switch 必须处理所有可能的枚举值,因此如果将新值添加到枚举中,则必须更改 switch,这就是为什么我添加引发异常的 default

问题是在代码运行并且控制通过 default 并抛出异常之前没有错误指示(顺便说一句,异常可以在调用堆栈的某个地方被抑制)。

我想在这里有一个编译时错误。例如,Visual C++ 可以发出 C4062 warning当没有 default 并且一个或多个值未处理时,该警告可以升级为错误。我本可以在我的代码中删除 default 并利用该警告。

我可以在 C# 中有类似的东西吗?

最佳答案

不,您需要编写单元测试。编译器不会为你做那件事。

单元测试可能类似于:

public void TestSwitch()
{
    foreach (var variable in (SomeEnum[])Enum.GetValues(typeof(SomeEnum)))
        Assert.DoesNotThrow(() => YourMethod(variable), "Value {0} not supported", variable);
}

取决于您的测试框架。

实际上,基础整数类型的任何值都是可能的(例如,如果基础类型是 int,它几乎总是是所有 4,294,967,296 个值)都是可能的,而且你永远不会写那么多 case 标签,我想。我知道您只需要带名称的值,但正如我所说,编译器不会为您检查。它只检查两个 case 是否引用相同的值。

我建议你放:

if (!Enum.IsDefined(typeof(SomeEnum), variable))
    throw new InvalidOperationException();

在某处,如果您的枚举没有 [Flags] 属性,但它显然只在运行时有效。

关于c# - 当开关不处理一个或多个枚举值时,我可能会出现 C# 编译时错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22192470/

相关文章:

c# - .net 中对象的装箱发生在什么级别?

gcc/clang 可以优化初始化计算吗?

c - 编译时数字的位位置

c# - 转发器中的 ASP.NET 用户控件属性在回发后为空

c# - 如何检查应用程序是否有权访问目录?

c# - 如何使用 ItemSsource 向 WPF ListBox 添加附加项?

c++ - C++ 中的 sizeof 是在编译时还是运行时评估的?

c# - 如何高效地将 IList<byte> 转换为 byte[]?

c# - 从上到下的尺寸

c# - 对所有项目同时执行 foreach block ?