System.Linq捉虫记 | 论变量命名的重要性
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了System.Linq捉虫记 | 论变量命名的重要性相关的知识,希望对你有一定的参考价值。
前言
下面这段代码,你能发现什么问题吗?
List<int> a = new List<int>{ 1, 2, 3, 4, 5 };
var last2 = a.TakeLast(2);
foreach (var item in last2)
{
Console.WriteLine(item);
}
a.AddRange(new[] { 11, 12, 13, 14, 15 });
foreach (var item in last2)
{
Console.WriteLine(item);
}
你能说出2次Console.WriteLine
的输出结果吗?
是4 5 4 5
还是4 5 14 15
?
其实答案是:
你没看错,第2次会出现3个元素。
原因
这并不是我们的代码有问题,而是System.Linq的Bug。
我们直接调试了dotnet/runtime源代码,发现调用TakeLast
时生成了ListPartition对象:
关键是_maxIndexInclusive
赋值是5(Count),按我的理解不应该是4(Index)吗!?
这就导致了下面的问题,当我们增加了元素后,它是这样计算的:
private int Count
{
get
{
int count = _source.Count;
if (count <= _minIndexInclusive)
{
return 0;
}
return Math.Min(count - 1, _maxIndexInclusive) - _minIndexInclusive + 1;
}
}
在这里,_maxIndexInclusive又是按Index理解的:
Math.Min(count - 1, _maxIndexInclusive) - _minIndexInclusive + 1
如果还是将_maxIndexInclusive按Count理解,就是正确的了:
Math.Min(count, _maxIndexInclusive) - _minIndexInclusive
结论
我怀疑,这是由于2个程序员分别实现的功能,导致对变量名含义理解不一致造成的BUG。
这也说明,起个意义明确的变量名是多么重要啊!
以上是关于System.Linq捉虫记 | 论变量命名的重要性的主要内容,如果未能解决你的问题,请参考以下文章
[原]捉虫记3:_ConectionPtr指针调用open失败