英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论