Resharper警告在switch case中:”源表达式始终与提供的模式匹配”

huangapple go评论89阅读模式
英文:

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

问题

Resharper显示警告:“源表达式始终与提供的模式匹配”,并在最后一个case语句的case int下划线标记。
Roslyn修复是“to object pattern”,并将其更改为case { } upperLvl when upperlevel >= 20

有人能解释为什么会显示这个警告吗,我是否应该应用这个更改?

英文:

Resharper is showing a warning "The source expression always matches the provided pattern" and underlining the case int of the last case statement.
The roslyn fix is "to object pattern" and changes it to case { } upperLvl when upperlevel >= 20

Can anybody enlighten me as to why this warning is shown and if I should apply that change?

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;
        }
    }

答案1

得分: 3

ReSharper因为int类型表达式始终匹配int upperLvl类型模式,换句话说,指定相同的类型是多余的,所以提出了此警告。将类型模式转换为对象模式({})提供了等效语义(你可以在此处检查:https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA+ABATARgLABQGAzAATakDCpA3oaQ+WRiqQLIAUAlLfYwL58GQpuRxJSAExhgAlgFsAhgBsqKsAFdligC4xKEDQAcIAOwBqKjTA6zTO0spgA3GMq4i6BRj9IBnAHdZHTAAC1IOJ1d3ER8vXwSpGAAzRS0dEFjEnwwAdlIsAAYAbiyEsEU/GFIADkzvbMYKqtIATnrGpsrqnEKOzt88goBWUobO5p6cfonu0hwsGcbJ+eIlgfJ84hKy3xWcFHXE/eGj8rnxM8ah4lHdn33cq4eLuvuulpx294ShlB3xss5jR+KRjEYYFAADLOVQBUIwUxgowQ6Gw0gAPgAvAU+qQAPT4gAqCP8higYGqMAQRlgfj8sjMpBUAUUAE8/KQlCEEZydKTaRBnLJpJJSEZdHooKYfoN8sMAdlBIDlfwgA=),但个人更喜欢在这种情况下使用var pattern

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

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

请注意,所有这些选项在这里是等效的,因为你正在对值类型的表达式进行切换,但在涉及引用类型时有微妙的区别。

假设你正在对某个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;
    }
}

这里的string specialCode类型模式执行空检查,意味着null值不匹配这个模式。

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

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

你可以快速查看C#如何将所有这些高级构造降低到这个精彩的网站https://sharplab.io/。

最后,是否应用ReSharper提出的修复决定总是由你决定!如果你真的喜欢类型模式语法,可以将此特定检查的严重性从Warning更改为Hint,甚至完全禁用它:只需在突出显示的代码上按Alt+Enter,展开菜单项Inspection: "The source expression is always of pattern's type" | Configure inspection severity,然后选择最适合你的其他严重性:)

英文:

ReSharper issues this warning because expression of type int indeed always matches type pattern int upperLvl, in other words specifying the same type is redundant. The proposed transformation of type pattern into object pattern ({}) gives equivalent semantics (you may check it here) but personally I prefer var pattern in such cases:

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

which also preseves the original semantics. The var pattern always succeeds but kind of indicates that you just want to introduce new variable here.

Note that all these options are equivalent here because you're switching on expression of value type but there are subtle differences when it comes to reference types.

Let's say you're switching on some string value:

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;
    }
}

Here type pattern string specialCode performs the null check meaning that null value doesn't match this pattern.

Replacing the type pattern with object pattern {} specialCode is equivalent because object pattern also performs null check.

But using the var pattern instead would change the semantics because as I mentioned earlier it always succeeds without performing any additional checks.

You can quickly check how C# lowers all these high-level constructs at wonderful website https://sharplab.io/.

And finally. The decision on whether to apply the fix proposed by ReSharper is always up to you! If you really prefer the type pattern syntax you may change severity of this particular inspection from Warning to Hint or even disable it completely: just press Alt+Enter on highlighted code, expand the menu item Inspection: "The source expression is always of pattern's type" | Configure inspection severity and select another severity which works best for you Resharper警告在switch case中:”源表达式始终与提供的模式匹配”

huangapple
  • 本文由 发表于 2020年1月3日 17:44:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/59576236.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定