空数组的“Equals”定义及.NET和.NET Core之间的区别

6

我昨天写了一些单元测试,它们在 .NET 4.6.1 中通过了测试,但在 .NET core 3.0 中失败了,因为在这个测试中生成的数组实例数量在两个环境中是不同的。经过一些调查发现,使用 LINQ 创建的空数组的数量不同。最终,我将其简化到以下测试:

    [Test]
    public void ArrayTest()
    {
        var numbers = Enumerable.Range(1, 5);

        int[] items1 = numbers.Where(i => i > 5).ToArray();
        int[] items2 = numbers.Where(i => i > 5).ToArray();

        Assert.IsFalse(items1 == items2);      // fails in .NET core 3 but passes in .NET 461
        Assert.IsFalse(items1.Equals(items2)); // fails in .NET core 3 but passes in .NET 461
    }

我的问题是:有人知道这个实现的不同之处在哪里吗?在.NET Core中,如果集合没有元素,ToArray()是否会返回Array.Empty<>单例实例而在.NET中则不会?

1个回答

5

如果集合没有元素,ToArray()在.NET Core中是否可能返回一个Array.Empty<>单例实例,但在.NET中不会?

是的。在.NET Core中,Linq进行了很多速度优化。

在.NET Framework中,Enumerable.ToArray()调用Buffer<TElement>.ToArray(),如果缓冲区为空,则返回new TElement [0]

在.NET Core中,对于您特定的情况<array>.Where(...).ToArray()Enumerable.ToArray()调用IIListProvider<TSource>.ToArray(),该方法由WhereArrayIterator<TSource>.ToArray()实现,它调用new LargeArrayBuilder<TSource>(_source.Length),该方法使用Array.Empty<T>

谢谢您的快速回答!我已经能够更新我的生产代码,以便在两个环境中都能通过。 - Döharrrck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接