В недавнем интервью меня спросили что различие между .Any()
и .Length > 0
был и почему я буду использовать также при тестировании, чтобы видеть, имел ли набор элементы.
Это бросило меня немного, поскольку это кажется немного очевидным, но чувство я могу пропускать что-то.
Я предложил, чтобы Вы использовали .Length
когда просто необходимо знать, что набор имеет элементы и .Any()
когда Вы хотите отфильтровать результаты.
По-видимому, .Any()
получает удар производительности также, поскольку он должен сделать цикл / запрос внутренне.
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;
}
Я предполагаю, что интервьюер, возможно, хотел спросить о проверке 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
, если вы просто хотите убедиться, что коллекция не пуста .
.Length ... System.Array .Любой ... IEnumerable (метод расширения).
Я бы предпочел использовать слово «длина», когда смогу его найти. Свойство в любом случае легче, чем вызов любого метода.
Тем не менее, реализация Any не будет делать ничего, кроме приведенного ниже кода.
private static bool Any<T>(this IEnumerable<T> items)
{
return items!=null && items.GetEnumerator().MoveNext();
}
Также, Лучшим вопросом могла бы быть разница между ".Count" и ".Length", что сказать :).
Длина
- это свойство типов массивов, а Any ()
- это метод расширения Enumerable
. Следовательно, вы можете использовать Length только при работе с массивами. При работе с более абстрактными типами ( IEnumerable
) вы можете использовать Any ().
Мы знаем, что .Length используется только для массивов, а .Any() - для коллекций IEnumerable.
Вы можете поменять .Count на .Length, и у вас останется тот же вопрос для работы с коллекциями IEnumberable
И .Any(), и .Count выполняют проверку на нуль перед началом перечислителя. Так что с точки зрения производительности они одинаковы.
Что касается массива, предположим, что у нас есть следующая строка:
int[] foo = new int[10];
Здесь foo.Length равно 10. Хотя это правильно, это может быть не тот ответ, который вы ищете, потому что мы еще ничего не добавили в массив. Если foo равен null, то возникнет исключение.
Я думаю, что это более общий вопрос о том, что выбрать, если у нас есть 2 способа выразить что-либо. В такой ситуации я бы предложил высказывание: «Будьте конкретны», цитата из Питера Норвига из его книги PAIP
. Будьте конкретны, значит, используйте то, что лучше всего описывает то, что вы делаете. Таким образом, вы хотите сказать что-то вроде:
collection.isEmpty()
Если у вас нет такой конструкции, я выберу общую идиому, которую использовали сообщества.
Для меня .Length> 0
не самый лучший вариант, поскольку он требует, чтобы вы могли изменять размер объекта.
Предположим, у вашей реализации бесконечный список. . Длина
явно не работает.
Звучит очень похоже на этот вопрос на Stackoverflow о разнице между .Count и .Any для проверки существования результата: Проверка существования результата в Linq-to-xml
В этом случае лучше использовать Any, а не Count, так как Count будет итерировать все элементы IEnumerable