7

在 C# 8 中,引入了 switch 表达式。如果 switch 表达式不详尽会发生什么?换句话说,如果我不测试每个可能的值会发生什么?

    static void Main(string[] args)
    {
        int x = 1;
        int imExhaustive = x switch
        {
            3 => 4,
            _ => 0   // x = 1 matches this
        };
        int okFine = x switch
        {
            1 => 4   // x = 1 matches this
        };
        int noMatch = x switch
        {
            3 => 4   // No match
        };
    }
4

3 回答 3

7

如果switch表达式不是详尽无遗的,编译器会产生警告。在运行时,如果您传递一个未处理的值,SwitchExpressionException则会抛出 a。

这记录在 C# 8.0 中的新模式功能的 speclet 中:https ://github.com/dotnet/csharplang/blob/master/proposals/csharp-8.0/patterns.md#switch-expression

如果编译器证明(使用这些技术)某些可能的输入值在运行时可能与某些 switch_expression_arm 不匹配,则编译器将产生警告。

在运行时,switch_expression 的结果是第一个 switch_expression_arm 的表达式的值,switch_expression 左侧的表达式与 switch_expression_arm 的模式匹配,并且 switch_expression_arm 的 case_guard(如果存在)对其求值为真。

如果没有这样的 switch_expression_arm,则 switch_expression 会引发异常 System.Runtime.CompilerServices.SwitchExpressionException 的实例。

于 2019-05-09T22:23:15.233 回答
1

要看。

如果有匹配:匹配,一切都很好。

如果没有匹配:SwitchExpressionException抛出A。

最佳实践似乎是编写详尽的开关表达式。如果你不这样做,并且没有爆炸,你可能只是走运了。

如果你的 switch 表达式不详尽,编译器会警告你,但这不是错误,它会编译并运行。

(刚刚遇到这个,所以我想我会分享 - 尽管 C# 8 仍处于预览阶段,但它还没有出现在文档中)

于 2019-05-09T21:54:00.797 回答
0

要删除此警告,请添加默认表达式。

   exception switch
    {
        ValidationException vExp => new ValidationErrorDetail
        {
            
        },
        ApiException apiExp => new ApiErrorDetail
        {
           
        },
        ProcessException pExp => new ErrorDetail
        {
           
        },
        _ => new ErrorDetail
        {

        }
    };

添加_ =>和要执行的默认表达式。

于 2021-01-18T11:36:06.547 回答