C# switch表达式异常排查:提取变量后为何恢复正常?
为什么C#中直接在switch表达式里使用
hi - (k - 1)会导致异常行为? 这是C#运算符优先级导致的问题,你的原代码执行逻辑和预期完全不符。
错误代码的实际执行逻辑
C#中switch表达式的优先级高于减法运算符(-),所以你写的:
return hi - (k - 1) switch { > 0 => FindKthLargest(nums[..hi], k), < 0 => FindKthLargest(nums[(hi + 1)..], k - hi - 1), _ => nums[hi] };
会被编译器解析成:
return hi - ( (k - 1) switch { > 0 => FindKthLargest(nums[..hi], k), < 0 => FindKthLargest(nums[(hi + 1)..], k - hi - 1), _ => nums[hi] } );
也就是先对k-1的值进行switch判断,把递归调用的返回值(或者nums[hi])当作结果,再用hi减去这个结果——这完全偏离了你原本要判断hi - (k-1)正负的逻辑。
拿你给出的测试用例来说:nums = [3,2,1,5,6,4]、k=2,此时k-1=1,会匹配switch的>0分支,递归调用FindKthLargest得到某个值,再用hi(假设此时为5)减去这个值,最终得到数组里不存在的8,这就是异常的根源。
修正代码为什么正常
把hi - (k-1)提取到变量wtf后,switch表达式的判断对象明确是这个变量的计算结果:先算出hi - (k-1)的值,再根据这个值的正负走对应分支,完全符合你的逻辑,自然就恢复正常了。
补充验证
C#官方的运算符优先级规则里,switch表达式属于高优先级的表达式类别,优先级高于算术减法,所以才会出现这种“代码写法和执行逻辑不一致”的情况。
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

