Рекомендуемый способ проверить, пуста ли последовательность

Метод возвращает последовательность, IEnumerable<T>, и Вы теперь хотите проверить, пусто ли это. Как Вы рекомендуете делать это? Я ищу и хорошую удобочитаемость и хорошую производительность.

Первый и самый очевидный путь состоит в том, чтобы проверить, что количество больше, чем нуль:

if(sequence.Count() == 0)

Имеет достойную удобочитаемость, но ужасная производительность, так как она должна на самом деле пройти целую последовательность.

Метод, который я иногда использую, следующий:

if(!sequence.Any())

Это не делает (насколько я знаю), должны пройти целую последовательность, но удобочитаемость немного назад и неловкая. (Чтения намного лучше, если мы проверяем, что последовательность не пуста хотя).

Другая опция состоит в том, чтобы использовать First в выгоде попытки, как это:

try
{
    sequence.First();
}
catch(InvalidOperationException)
{
    // Do something
}

Не очень симпатичное решение, и вероятно медленнее также, так как это использует исключения и материал. Мог предотвратить это при помощи FirstOrDefault конечно, кроме Вас имел бы большую проблему, если бы первый объект в последовательности на самом деле был значением по умолчанию ;)

Так, какие-либо другие способы проверить, пуста ли последовательность? Какой Вы обычно используете? Какой Вы рекомендуете использовать?

Примечание: Для оптимальной удобочитаемости я, вероятно, поместил бы один из вышеупомянутых отрывков в IsEmpty дополнительный метод, но мне все еще любопытно, так как я должен был бы сделать что-то в том методе также :p

47
задан abatishchev 24 April 2017 в 17:28
поделиться

4 ответа

Я бы использовал ! Sequence.any () , лично.

Если вы действительно надо, вы всегда можете написать свой собственный метод расширения:

public static bool IsEmpty<T>(this IEnumerable<T> source)
{
    return !source.Any();
}

, тогда вы можете написать:

if (sequence.IsEmpty())
81
ответ дан 26 November 2019 в 19:40
поделиться

Вы можете создать метод расширения, с этой реализацией.

public static bool IsEmpty<T>(this IEnumerable<T> items) {
        using (var enumerator = items.GetEnumerator())
        {
            return !enumerator.MoveNext();
        }
 }
6
ответ дан 26 November 2019 в 19:40
поделиться

Ну, все эти методы, которые вы звоните, представляют собой методы расширения LINQ, поэтому это зависит от того, как был реализован поставщик LINQ. Если вы хотите знать, является ли последовательность пустой, либо подсчет () == 0 или любой () == false . Я предпочитаю любой () сам.

Однако в зависимости от того, какой фактический тип ваша последовательность , вам, возможно, не нужно использовать метод расширения LINQ. Я Если это массив, вы можете вызвать последовательность. Длина . Если это коллекция, вы можете использовать Sequence.Count .

2
ответ дан 26 November 2019 в 19:40
поделиться

Вы сказали:

если (Sequence.count () == 0) Имеет достойную читаемость, но ужасную производительность, поскольку она должна фактически пройти через всю последовательность.

Это на самом деле правда? Вы говорите о работе с интерфейсом , IENumerable , и все же вы делаете предположения о его реализации, которые могут быть или не могут быть верны. Фактически, многие из нестандартных коллекций, которые я написал в течение многих лет, сохраняет частную переменную, которая хранит текущее количество внутренне, что означает, что возвращение .Count - это тривиальное значение, которое не требует итерации всей коллекции Отказ

Так что с этим сказано, если вы не знаете, что конкретная реализация плохо оптимизирована для .Count , я бы использовал .Count . Избегайте преждевременной оптимизации, где это возможно, и придерживайтесь читаемости.

0
ответ дан 26 November 2019 в 19:40
поделиться
Другие вопросы по тегам:

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