Вопрос об интервью:.Any (), по сравнению с если (.Length> 0) для тестирования, если набор имеет элементы

В недавнем интервью меня спросили что различие между .Any() и .Length > 0 был и почему я буду использовать также при тестировании, чтобы видеть, имел ли набор элементы.

Это бросило меня немного, поскольку это кажется немного очевидным, но чувство я могу пропускать что-то.

Я предложил, чтобы Вы использовали .Length когда просто необходимо знать, что набор имеет элементы и .Any() когда Вы хотите отфильтровать результаты.

По-видимому, .Any() получает удар производительности также, поскольку он должен сделать цикл / запрос внутренне.

18
задан 2 revs, 2 users 100% 7 June 2010 в 12:13
поделиться

7 ответов

Length существует только для некоторых типов коллекций, таких как Array.

Any - это метод расширения, который можно использовать с любой коллекцией, реализующей IEnumerable.

Если присутствует Length, то можно использовать его, иначе используйте Any.


Предположительно, .Any() также снижает производительность, поскольку ему приходится выполнять цикл/запрос внутри.

Enumerable.Any не зацикливается. Он получает итератор и проверяет, возвращает ли MoveNext true. Вот исходный код из .NET Reflector.

public static bool Any<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        if (enumerator.MoveNext())
        {
            return true;
        }
    }
    return false;
}
24
ответ дан 30 November 2019 в 07:22
поделиться

Я предполагаю, что интервьюер, возможно, хотел спросить о проверке Any () по сравнению с Count ()> 0 (в отличие от Length> 0 ).

В принципе, вот в чем дело.

Any () будет эффективно пытаться определить, есть ли в коллекции какие-либо члены, перечисляя по одному элементу. (Существует перегрузка для проверки данного критерия с использованием Func , но я предполагаю, что интервьюер имел в виду версию Any () , которая принимает без аргументов.) Это делает его O (1).

Count () проверит наличие свойства Length или Count (из T [] или ICollection ] или ICollection ) первым. Обычно это O (1). Однако, если он недоступен, он будет подсчитывать элементы в коллекции, перечисляя все элементы. Это было бы O (n).

Свойство Count или Length , если доступно, скорее всего, будет O (1), как Any () , и, вероятно, будет работать лучше, поскольку для этого не требуется никакого перечисления. Но метод расширения Count () не гарантирует этого. Поэтому иногда это O (1), иногда O (n).

Предположительно, если вы имеете дело с невзрачным IEnumerable и не знаете, реализует ли он ICollection или нет, вы Намного лучше использовать Any () , чем Count ()> 0 , если вы просто хотите убедиться, что коллекция не пуста .

13
ответ дан 30 November 2019 в 07:22
поделиться

.Length ... System.Array .Любой ... IEnumerable (метод расширения).

Я бы предпочел использовать слово «длина», когда смогу его найти. Свойство в любом случае легче, чем вызов любого метода.

Тем не менее, реализация Any не будет делать ничего, кроме приведенного ниже кода.

 private static bool Any<T>(this IEnumerable<T> items)
        {
            return items!=null && items.GetEnumerator().MoveNext();
        }

Также, Лучшим вопросом могла бы быть разница между ".Count" и ".Length", что сказать :).

1
ответ дан 30 November 2019 в 07:22
поделиться

Длина - это свойство типов массивов, а Any () - это метод расширения Enumerable . Следовательно, вы можете использовать Length только при работе с массивами. При работе с более абстрактными типами ( IEnumerable ) вы можете использовать Any ().

1
ответ дан 30 November 2019 в 07:22
поделиться

Мы знаем, что .Length используется только для массивов, а .Any() - для коллекций IEnumerable.

Вы можете поменять .Count на .Length, и у вас останется тот же вопрос для работы с коллекциями IEnumberable

И .Any(), и .Count выполняют проверку на нуль перед началом перечислителя. Так что с точки зрения производительности они одинаковы.

Что касается массива, предположим, что у нас есть следующая строка:

int[] foo = new int[10];

Здесь foo.Length равно 10. Хотя это правильно, это может быть не тот ответ, который вы ищете, потому что мы еще ничего не добавили в массив. Если foo равен null, то возникнет исключение.

0
ответ дан 30 November 2019 в 07:22
поделиться

Я думаю, что это более общий вопрос о том, что выбрать, если у нас есть 2 способа выразить что-либо. В такой ситуации я бы предложил высказывание: «Будьте конкретны», цитата из Питера Норвига из его книги PAIP

. Будьте конкретны, значит, используйте то, что лучше всего описывает то, что вы делаете. Таким образом, вы хотите сказать что-то вроде:

collection.isEmpty()

Если у вас нет такой конструкции, я выберу общую идиому, которую использовали сообщества. Для меня .Length> 0 не самый лучший вариант, поскольку он требует, чтобы вы могли изменять размер объекта. Предположим, у вашей реализации бесконечный список. . Длина явно не работает.

0
ответ дан 30 November 2019 в 07:22
поделиться

Звучит очень похоже на этот вопрос на Stackoverflow о разнице между .Count и .Any для проверки существования результата: Проверка существования результата в Linq-to-xml

В этом случае лучше использовать Any, а не Count, так как Count будет итерировать все элементы IEnumerable

0
ответ дан 30 November 2019 в 07:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: