开关盒中的 Resharper 警告 "The source expression always matches the provided pattern"

Resharper warning in switch case "The source expression always matches the provided pattern"

Resharper 显示警告 "The source expression always matches the provided pattern" 并在最后一个 case 语句的 case int 下划线。 roslyn 修复是 "to object pattern" 并将其更改为 case { } upperLvl when upperlevel >= 20

任何人都可以告诉我为什么显示此警告以及我是否应该应用该更改?

public static decimal CalculateCouponValue(int level)
    {
        switch (level)
        {
            default:
                return 20;
            case 8:
            case 9:
            case 10:
                return 25;
            case 11:
            case 12:
            case 13:
                return 30;
            case 14:
            case 15:
            case 16:
                return 35;
            case 17:
            case 18:
            case 19:
                return 40;
            case int upperLvl when upperLvl >= 20: //The source expression always matches the provided pattern
                return 50;
        }
    }

ReSharper 发出此警告是因为 int 类型的表达式确实总是匹配 类型模式 int upperLvl,换句话说,指定相同类型是多余的。建议将 type pattern 转换为 object pattern ({}) 给出等效的语义(你可以检查它 here)但我个人更喜欢 var pattern 在这种情况下:

case var upperLvl when upperLvl >= 20:
    return 50;

这也保留了原始语义。 var 模式 总是成功 但有点表明你只想在这里引入新变量。

请注意,所有这些选项在这里都是等价的,因为您打开了 值类型 的表达式,但是在涉及 引用类型时存在细微差别.

假设您要打开某个 string 值:

public static decimal GetDiscountByCode(string code)
{
    switch (code.ToUpper())
    {
        case "XMAS2020":
            return 25;
        case "NEWYEAR2020":
            return 20;
        case string specialCode
          when TryExtractDiscount(specialCode, out var discount):
            return discount;
        default:
            return 0;
    }
}

此处 type pattern string specialCode 执行 null 检查 意味着 null 值与此不匹配模式。

对象模式替换类型模式 {} specialCode是等价的,因为对象模式 也执行空值检查.

但是使用 var 模式 会改变语义,因为正如我之前提到的,它总是成功而不执行任何额外的检查。

您可以在精彩的网站 https://sharplab.io/.

上快速查看 C# 如何降低 所有这些高级构造

最后。是否应用 ReSharper 提出的修复始终由您决定!如果您真的更喜欢类型模式语法,您可以将此特定检查的严重性从 Warning 更改为 Hint 甚至完全禁用它:只需在突出显示的代码上按 Alt+Enter,展开菜单项 检验:"The source expression is always of pattern's type" |配置检查严重性 和 select 另一个最适合您的严重性:)