¿Cómo comprobar si IEnumerable es nulo o está vacío?

Me encanta el método string.IsNullOrEmpty . Me encantaría tener algo que permita la misma funcionalidad para IEnumerable. ¿Hay tal? Tal vez alguna clase de ayuda de colección? La razón por la que estoy preguntando es que en las declaraciones if , el código parece desordenado si el patrón es (mylist != null && mylist.Any()) . Sería mucho más limpio tener Foo.IsAny(myList) .

Esta publicación no da esa respuesta: ¿ IEnumerable está vacío? .

Claro que podrías escribir eso:

 public static class Utils { public static bool IsAny(this IEnumerable data) { return data != null && data.Any(); } } 

sin embargo, tenga cuidado de que no todas las secuencias sean repetibles; en general , prefiero caminar solo una vez, por las dudas.

 public static bool IsNullOrEmpty(this IEnumerable enumerable) { return enumerable == null || !enumerable.Any(); } 

Aquí hay una versión modificada de la útil respuesta de @Matt Greer que incluye una clase contenedora estática para que pueda copiar y pegar esto en un nuevo archivo fuente, no dependa de Linq, y agregue una IEnumerable genérica IEnumerable , para evitar el boxeo de los tipos de valor que se producirían con la versión no genérica. [EDITAR: IEnumerable cuenta que el uso de IEnumerable no previene el encajonamiento del enumerador, pato-tipado no puede evitar eso, pero al menos los elementos en una colección de valores de tipo no serán encasillados.]

 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(this IEnumerable source) { if (source != null) { foreach (T obj in source) { return false; } } return true; } } 

Otra forma sería obtener el Enumerador y llamar al método MoveNext () para ver si hay algún elemento:

 if (mylist != null && mylist.GetEnumerator().MoveNext()) { // The list is not null or empty } 

Esto funciona tanto para IEnumerable como para IEnumerable .

La forma en que lo hago, aprovechando algunas características modernas de C #:

Opción 1)

 public static class Utils { public static bool IsNullOrEmpty(this IEnumerable list) { return !(list?.Any() ?? false); } } 

Opcion 2)

 public static class Utils { public static bool IsNullOrEmpty(this IEnumerable list) { return !(list?.Any()).GetValueOrDefault(); } } 

Y, por cierto, nunca use Count == 0 o Count() == 0 solo para verificar si una colección está vacía. Siempre use Linq’s .Any()

Aquí está el código de la respuesta de Marc Gravell , junto con un ejemplo de su uso.

 using System; using System.Collections.Generic; using System.Linq; public static class Utils { public static bool IsAny(this IEnumerable data) { return data != null && data.Any(); } } class Program { static void Main(string[] args) { IEnumerable 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."); } } } 

Como él dice, no todas las secuencias son repetibles, por lo que el código a veces puede causar problemas, porque IsAny() comienza a recorrer la secuencia. Sospecho que la respuesta de Robert Harvey fue que a menudo no necesitas verificar si está vacío o no. A menudo, puedes verificar null y luego usar foreach .

Para evitar comenzar la secuencia dos veces y aprovechar foreach , acabo de escribir un código como este:

 using System; using System.Collections.Generic; using System.Linq; class Program { static void Main(string[] args) { IEnumerable 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."); } } } 

Supongo que el método de extensión te ahorra un par de líneas de tipeo, pero este código me parece más claro. Sospecho que algunos desarrolladores no se darán cuenta inmediatamente de que IsAny(items) realmente comenzará a recorrer la secuencia. (Por supuesto, si está usando muchas secuencias, aprende rápidamente a pensar qué pasos tomar).

Comenzando con C # 6 puede usar la propagación nula : myList?.Any() == true

Si aún te parece demasiado obsoleto o prefieres un buen método de extensión, te recomendaría las respuestas de Matt Greer y Marc Gravell, pero con un poco de funcionalidad extendida para que esté completo.

Sus respuestas proporcionan la misma funcionalidad básica, pero cada una desde otra perspectiva. La respuesta de Matt usa el string.IsNullOrEmpty -mentality, mientras que la respuesta de Marc toma el camino .Any() Linq para hacer el trabajo.

Personalmente estoy inclinado a usar el camino .Any() , pero me gustaría agregar la función de comprobación de condición de la otra sobrecarga del método:

  public static bool AnyNotNull(this IEnumerable source, Func predicate = null) { if (source == null) return false; return predicate == null ? source.Any() : source.Any(predicate); } 

Por lo tanto, puede hacer cosas como: myList.AnyNotNull(item=>item.AnswerToLife == 42); como podría con el regular. .Any() pero con el cheque nulo agregado

Tenga en cuenta que con la forma C # 6: myList?.Any() devuelve un bool? en lugar de un `bool, que es el efecto real de propagar nulo

Esto puede ayudar

 public static bool IsAny(this IEnumerable enumerable) { return enumerable?.Any() == true; } public static bool IsNullOrEmpty(this IEnumerable enumerable) { return enumerable?.Any() != true; } 

Yo uso Bool IsCollectionNullOrEmpty = !(Collection?.Any()??false); . Espero que esto ayude.

Descompostura:

Collection?.Any() devolverá null si Collection es nulo y false si Collection está vacío.

Collection?.Any()??false nos dará false si Colección está vacía, y false si Collection es null .

Complemento de eso nos dará IsEmptyOrNull .

Tuve el mismo problema y lo resuelvo como:

  public bool HasMember(IEnumerable Dataset) { return Dataset != null && Dataset.Any(c=>c!=null); } 

“c => c! = null” ignorará todas las entidades nulas.

simplemente agregue using System.Linq y vea la magia que ocurre cuando intenta acceder a los métodos disponibles en IEnumerable . Agregar esto le dará acceso a un método llamado Count() tan simple como eso. solo recuerde verificar el null value antes de llamar a count() 🙂

Utilicé simple si para verificarlo

mira mi solución

 foreach (Pet pet in v.Pets) { if (pet == null) { Console.WriteLine(" No pet");// enumerator is empty break; } Console.WriteLine(" {0}", pet.Name); } 

Construí esto con la respuesta de @Matt Greer

Respondió perfectamente a la pregunta del OP.

Quería algo así mientras mantuve las capacidades originales de Any mientras también buscaba null. Estoy publicando esto en caso de que alguien más necesite algo similar.

Específicamente, quería seguir siendo capaz de transmitir un predicado.

 public static class Utilities { // Will return true if it is not null and contains elements. public static bool NotNullAny(this IEnumerable 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(this IEnumerable enumerable, Func predicate) { return enumerable != null && enumerable.Any(predicate); } } 

El nombre del método de extensión podría ser mejor.

La otra mejor solución como la siguiente para comprobar si está vacío o no?

 for(var item in listEnumerable) { var count=item.Length; if(count>0) { // not empty or null } else { // empty } }