我可以强制使用非详尽的 C# 开关表达式来导致编译错误吗?

Jon*_*vin 10 c# roslyn-code-analysis

我喜欢将枚举映射到值的开关表达式 - 虽然不是最具可扩展性的解决方案,但如果枚举代表某种模式(并且不是很大),它会快速且相当干净。

错误的一个常见来源是向枚举添加成员 - 这通常会导致新情况得不到处理。

但我认为,如果我们能够为非详尽的开关提供编译错误,从而使遗漏变得易于可见和修复,那么这些错误几乎可以被消除。(默认情况必须省略,否则就没有意义了)

这可能吗?我在想这样的事情:

public string GetTargetValue()
{
    return target switch
   {
       Target.A => "foo",
       Target.B => "bar",
       // Compile error if someone added Target.C, otherwise works fine
       // no default case - it would defeat the point
   };
}
Run Code Online (Sandbox Code Playgroud)

PS:我主要在 Unity 中工作,但据我了解,较新版本的 Unity 使用 Roslyn 编译器(我不使用burst),所以我认为这并不重要。

can*_*on7 13

是的你可以。

这种情况会引发警告 CS8509,如您在此处看到的。要将其变成错误,请将以下内容添加到您的 .editorconfig 中:

dotnet_diagnostic.CS8509.severity = error
Run Code Online (Sandbox Code Playgroud)

您可能还想忽略 CS8524,如果您没有默认情况,并且未引发 CS8509,则会发生这种情况(因此即使您覆盖了所有可能的值),请参阅此处。在这种情况下,编译器将插入一个默认情况throw new SwitchExpressionException(target):

dotnet_diagnostic.CS8524.severity = none
Run Code Online (Sandbox Code Playgroud)

我怀疑您可能需要使用 .NET 5 SDK 或更高版本进行构建才能生成此警告。

  • @JonathanLevin 不?如果您包含所有案例,[您将得到 CS8524](https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA+ABATARgLABQGAzAATakDCpA3oaQ4wyaQJYB2ALqQOIycAVAIZQA5vwBqQgDYBXGAAphY/qU4jxnAJT0mjOgT1GMAdjUbVAZwD urTMAAWuo/ucu9yzQDoAgqQC8AHykOAA0bu6MnvxeAEIBwVjhhpEeFpxe1EGkxMmpegD0BVQQALYADqzSMKQwUFDQbABmpJZlMBDsNUIAJj0wPaTRGZShpBCcDnW2ljXW0ADWlqRNHDARqUWk7BCk/U2yMtxgQrOk cGzc87LSg/swQtyTNeUQHJwbegC+ANyfpF9CICCIQWDB2LJSkN0rRSD4xrExtQvkA===)。如果您愿意,可以选择忽略该选项。 (2认同)