Определение «Равно» для пустых массивов и разницы между ядром. NET и. NET - PullRequest
6 голосов
/ 30 апреля 2020

Вчера я написал несколько модульных тестов, которые проходят. 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
    }

Мой вопрос: кто-нибудь знает, где реализация отличается? Может ли ToArray () возвращать одноэлементный экземпляр Array.Empty <> в ядре. NET, но не в. NET, если в коллекции нет элементов?

1 Ответ

5 голосов
/ 30 апреля 2020

Может ли ToArray () возвращать одноэлементный экземпляр Array.Empty <> в. NET ядре, но не в. NET, если в коллекции нет элементов?

Да , Linq получил много оптимизаций скорости в. NET Core.

In. NET Framework, Enumerable.ToArray() вызывает Buffer<TElement>.ToArray(), что возвращает new TElement[0], если буфер пуст .

In. NET Core, для вашего конкретного c случая <array>.Where(...).ToArray(), Enumerable.ToArray() вызовов IIListProvider<TSource>.ToArray(), который реализуется WhereArrayIterator<TSource>.ToArray(), который вызывает new LargeArrayBuilder<TSource>(_source.Length), который использует Array.Empty<T>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...