【问题标题】:is there a warning (error), similar to C4061 for C#是否有警告(错误),类似于 C# 的 C4061
【发布时间】:2012-09-21 13:01:15
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 请为那些不熟悉 C++ Cxyz 警告的人解释警告。
  • msdn 中对它们进行了很好的解释。简而言之,在 C++ 代码中,如果启用它们,对某些枚举使用“switch”,而忘记处理某些枚举值(在单独的“case”中),您将在编译期间收到警告

标签: c# enums switch-statement compile-time


【解决方案1】:

不,没有编译时检查 - 有一个只处理一些命名值的 switch/case 是合法的。 可能包含它,但存在一些问题。

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

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

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

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

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

您可以使用Enum.IsDefined 预先检查此问题,但效率相对较低。

我同意所有这一切都有点痛苦 - 枚举对于 .NET 来说有点令人讨厌:(

【讨论】:

  • 谢谢。但我不同意“不,不能进行编译时检查。”。在 C++ 中,您也可以将任何值设置为枚举,但有机会检查您是否处理了所有预期值。
  • 也许你知道一些可以检查这个的 3rdparty 工具(比如 StyleCop)?
  • @Alek86:恐怕我不知道。 (这并不意味着它们不存在,只是我从未故意看到或使用过这样的功能。)使用 Roslyn,您可能可以自己编写,请注意 :)
  • 这个答案的很大一部分倾向于“处理未明确声明的枚举值”。然而,OP 的问题更多是关于“未能处理未明确声明的值”。 (确实 flag-enum 是不同的,C# 至少可以将它们分开一点。)
  • 回复:“只想回应少数情况”......当然,但应该考虑未来对枚举的更改。添加一个新值时,默认处理可能不正确。编译器警告/错误在这里有帮助,类似于成员的新/覆盖关键字。
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 2014-09-08
    • 2010-09-08
    相关资源
    最近更新 更多