7

通常,如果我在 C# 中对枚举使用 switch,我必须编写类似的内容:

switch (e)
{
    case E.Value1:
        //...
        break;

    case E.Value2:
        //...
        break;

        //...
    default:
        throw new NotImplementedException("...");
}

在 C++(用于 VS)中,我可以为此开关启用警告 C4061 和 C4062,使它们出错并进行编译时检查。在 C# 中,我必须将此检查移至运行时...

有谁知道在 C# 中我如何在编译时检查这个?也许有一个警告,默认情况下禁用,我错过了,或者其他方式?

4

2 回答 2

6

不,没有编译时检查——拥有一个只处理一些命名值的开关/案例是合法的。本来可以包含它,但存在一些问题。

首先,枚举值没有任何“命名”值是完全有效的(不幸的是):

enum Foo
{
    Bar = 0,
    Baz = 1
}
...
Foo nastyValue = (Foo) 50;

鉴于任何值在 switch/case 中都是可行的,编译器无法知道您并不是要尝试处理未命名的值。

其次,它不适用于Flags枚举——编译器并不真正知道哪些值是方便的组合。它可以推断出这一点,但它会有点恶心。

第三,它并不总是你想要的——有时你真的只想回应几个案例。我不想有规律地抑制警告。

您可以使用Enum.IsDefined它预先检查这一点,但这相对低效。

我同意所有这一切都有点痛苦——当涉及到 .NET 时,枚举是一个令人讨厌的领域:(

于 2012-09-21T13:04:09.527 回答
2

我知道这是 necroposting,但在编译器内部的这个区域并没有真正改变。因此,我为 switch 语句制作了 Roslyn 分析器。您可以下载SwitchAnalyzer 软件包。 这是 Roslyn 分析器,它支持

  • 操作枚举 | 和 & 为他们。因此,您也可以检查标志(但不像单个 int 值)

  • 当前数据上下文中的接口实现(模式匹配)。

0.4 版还没有实现类的模式匹配(但我希望尽快实现)。要使用它,只需将此包添加到您的项目中,如果您没有默认分支或抛出异常,您将收到所有未发现案例的警告。当然,您可以为您的项目启用“将警告视为错误”选项以获取所有或特定警告。如果您发现任何错误,请随时与我联系。

于 2018-06-28T18:42:07.803 回答