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