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捉虫记 | 论变量命名的重要性的主要内容,如果未能解决你的问题,请参考以下文章

PHP网站 “新手”捉虫记

[原]捉虫记3:_ConectionPtr指针调用open失败

Cocos2d-x 3.8.1+Cocos Studio 2.3.2捉虫记之控制场景文件中的骨骼动画

学界论名字的重要性之Bellman动态规划的命名

using System.Linq ;啥意思

C—LINQ小结