Как проверить, является ли IEnumerable нулевым или пустым?
Я люблю string.IsNullOrEmpty метод. Я хотел бы иметь что-то, что позволит такую же функциональность для IEnumerable. Есть ли такие? Может быть, какой-то вспомогательный класс коллекции? Причина, по которой я спрашиваю, заключается в том, что в if операторы код выглядит загроможденным, если скороговорка (mylist != null && mylist.Any()). Было бы намного чище иметь Foo.IsAny(myList).
этот пост не дает такого ответа:IEnumerable пуст?.
14 ответов:
уверен, что вы может пишут, что:
public static class Utils { public static bool IsAny<T>(this IEnumerable<T> data) { return data != null && data.Any(); } }однако, будьте осторожны, что не все последовательности повторяемы;вообще Я предпочитаю ходить только один раз, на всякий случай.
public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable) { return enumerable == null || !enumerable.Any(); }
вот модифицированная версия полезного ответа @Matt Greer, которая включает статический класс-оболочку, поэтому вы можете просто скопировать-вставить это в новый исходный файл, не зависит от Linq и добавляет общий
IEnumerable<T>перегрузка, чтобы избежать бокса типов значений, которые будут происходить с неродовой версией. [EDIT: обратите внимание, что использованиеIEnumerable<T>не предотвращает бокс перечислителя,утка-типирование не могу этого предотвратить, но, по крайней мере, элементы в коллекции с типом значения не будут каждый упакованный.]using System.Collections; using System.Collections.Generic; public static class IsNullOrEmptyExtension { public static bool IsNullOrEmpty(this IEnumerable source) { if (source != null) { foreach (object obj in source) { return false; } } return true; } public static bool IsNullOrEmpty<T>(this IEnumerable<T> source) { if (source != null) { foreach (T obj in source) { return false; } } return true; } }
другой способ-получить перечислитель и вызвать метод MoveNext (), чтобы узнать, есть ли какие-либо элементы:
if (mylist != null && mylist.GetEnumerator().MoveNext()) { // The list is not null or empty }это работает для IEnumerable, а также IEnumerable
.
как я это делаю, пользуясь некоторыми современными функциями C#:
1)2)public static class Utils { public static bool IsNullOrEmpty<T>(this IEnumerable<T> list) { return !(list?.Any() ?? false); } }public static class Utils { public static bool IsNullOrEmpty<T>(this IEnumerable<T> list) { return !(list?.Any()).GetValueOrDefault(); } }и кстати, никогда не используйте
Count == 0илиCount() == 0просто чтобы проверить, если коллекция пуста. Всегда используйте Linq.Any()
здесь код Марк Gravell-это, а также пример его использования.
using System; using System.Collections.Generic; using System.Linq; public static class Utils { public static bool IsAny<T>(this IEnumerable<T> data) { return data != null && data.Any(); } } class Program { static void Main(string[] args) { IEnumerable<string> items; //items = null; //items = new String[0]; items = new String[] { "foo", "bar", "baz" }; /*** Example Starts Here ***/ if (items.IsAny()) { foreach (var item in items) { Console.WriteLine(item); } } else { Console.WriteLine("No items."); } } }как он говорит, не все последовательности повторяемы, так что код иногда может вызвать проблемы, потому что
IsAny()начинает шагать через последовательность. Я подозреваю, что ответ Роберта Харви означало, что вам часто не нужно проверятьnullи пустой. Часто, вы можете просто проверить на null, а затем использоватьforeach.To избегайте запуска последовательности дважды и воспользоваться
foreach, Я просто написал такой код:using System; using System.Collections.Generic; using System.Linq; class Program { static void Main(string[] args) { IEnumerable<string> items; //items = null; //items = new String[0]; items = new String[] { "foo", "bar", "baz" }; /*** Example Starts Here ***/ bool isEmpty = true; if (items != null) { foreach (var item in items) { isEmpty = false; Console.WriteLine(item); } } if (isEmpty) { Console.WriteLine("No items."); } } }Я думаю, что метод расширения экономит вам пару строк ввода, но этот код кажется мне более ясным. Я подозреваю, что некоторые разработчики не сразу поймут, что
IsAny(items)начнет шагать через последовательность. (Конечно, если вы используете много последовательностей, вы быстро научитесь думать о том, какие шаги сквозь них.)
начиная с C#6 Вы можете использовать нуль распространения:
myList?.Any() == trueесли вы все еще находите это слишком забитым или предпочитаете хороший метод расширения ol, я бы рекомендовал ответы Мэтта Грира и Марка Гравелла, но с немного расширенной функциональностью для полноты.
их ответы обеспечивают ту же основную функциональность, но каждый с другой точки зрения. Ответ Мэтта использует
string.IsNullOrEmpty-менталитет, тогда как ответ Марка принимает Linq.Any()дорога, чтобы получить работу.Я лично склонен использовать
.Any()дорога, но хотел бы добавить функциональность проверки условий из метода другие перегрузки:public static bool AnyNotNull<T>(this IEnumerable<T> source, Func<T, bool> predicate = null) { if (source == null) return false; return predicate == null ? source.Any() : source.Any(predicate); }так что вы все еще можете делать такие вещи, как :
myList.AnyNotNull(item=>item.AnswerToLife == 42);как вы могли с обычной.Any()но с добавленной нулевой проверкойобратите внимание, что с C#6 путь:
myList?.Any()возвращает abool?а не типа bool, которое, по сути распространяющейся null
Это может помочь
public static bool IsAny<T>(this IEnumerable<T> enumerable) { return enumerable?.Any() == true; } public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable) { return enumerable?.Any() != true; }
Я использую
Bool IsCollectionNullOrEmpty = !(Collection?.Any()??false);. Надеюсь, это поможет.поломки:
Collection?.Any()вернутсяnullЕсли коллекция равна нулю, иfalseесли коллекция пуста.
Collection?.Any()??falseдаст намfalseесли коллекция пуста, иfalseесли коллекцияnull.дополнение, которое даст нам
IsEmptyOrNull.
У меня была такая же проблема и я решаю ее так :
public bool HasMember(IEnumerable<TEntity> Dataset) { return Dataset != null && Dataset.Any(c=>c!=null); }" c= > c!=null " будет игнорировать все нулевые сущности.
просто добавить
using System.Linqи увидеть волшебство происходит, когда вы пытаетесь получить доступ к доступных способов вIEnumerable. Добавление этого даст вам доступ к методу с именемCount()вот так просто. просто не забудьте проверитьnull valueперед вызовомcount():)
я использовал простой, если проверить его
проверить мое решение
foreach (Pet pet in v.Pets) { if (pet == null) { Console.WriteLine(" No pet");// enumerator is empty break; } Console.WriteLine(" {0}", pet.Name); }
Я построил это от ответ @Matt Greer
он отлично ответил на вопрос ОП.
Я хотел что-то вроде этого, сохраняя исходные возможности любого, а также проверяя null. Я отправляю это на случай, если кому-то еще нужно что-то подобное.
в частности, я хотел все еще быть в состоянии передать предикат.
public static class Utilities { // Will return true if it is not null and contains elements. public static bool NotNullAny<T>(this IEnumerable<T> enumerable) { return enumerable != null && enumerable.Any(); } // Will return true if it is not null and contains elements that satisfy the condition. public static bool NotNullAny<T>(this IEnumerable<T> enumerable, Func<T, bool> predicate) { return enumerable != null && enumerable.Any(predicate); } }название метода расширения, вероятно, может быть лучше.
другое лучшее решение, как показано ниже, чтобы проверить пустой или нет ?
for(var item in listEnumerable) { var count=item.Length; if(count>0) { // not empty or null } else { // empty } }
Comments