c# ienumerable isnullorempty

¿Tiene C#IsNullOrEmpty para List/IEnumerable?



(9)

Sé que generalmente la lista vacía es más preferible que NULL. Pero voy a devolver NULL, principalmente por dos razones

  1. Debo verificar y manejar valores nulos explícitamente, evitando errores y ataques.
  2. Es fácil de realizar ?? operación posterior para obtener un valor de retorno.

Para cadenas, tenemos IsNullOrEmpty. ¿Hay algo desde C # que haga lo mismo para List o IEnumerable?


Como todos han dicho, nada está incorporado en el marco, pero si estás usando Castle entonces Castle.Core.Internal lo tiene.

using Castle.Core.Internal; namespace PhoneNumbers { public class PhoneNumberService : IPhoneNumberService { public void ConsolidateNumbers(Account accountRequest) { if (accountRequest.Addresses.IsNullOrEmpty()) // Addresses is List<T> { return; } ...


Modifiqué la sugerencia de Matthew Vines para evitar la "Enumeración múltiple posible de IEnumerable" - problema. (ver también el comentario de Jon Hanna)

public static bool IsNullOrEmpty(this IEnumerable items) => items == null || (items as ICollection)?.Count == 0 || !items.GetEnumerator().MoveNext();

... y la prueba de unidad:

[Test] public void TestEnumerableEx() { List<int> list = null; Assert.IsTrue(list.IsNullOrEmpty()); list = new List<int>(); Assert.IsTrue(list.IsNullOrEmpty()); list.AddRange(new []{1, 2, 3}); Assert.IsFalse(list.IsNullOrEmpty()); var enumerator = list.GetEnumerator(); for(var i = 1; i <= list.Count; i++) { Assert.IsFalse(list.IsNullOrEmpty()); Assert.IsTrue(enumerator.MoveNext()); Assert.AreEqual(i, enumerator.Current); } Assert.IsFalse(list.IsNullOrEmpty()); Assert.IsFalse(enumerator.MoveNext()); }


No hay nada incorporado

Sin embargo, es un método de extensión simple:

public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable) { if(enumerable == null) return true; return !enumerable.Any(); }


Si necesita poder recuperar todos los elementos en caso de que no estén vacíos, algunas de las respuestas aquí no funcionarán, porque la llamada a Any() en un enumerable no rewindable "olvidará" un elemento.

Podría tomar un enfoque diferente y convertir los valores nulos en vacíos:

bool didSomething = false; foreach(var element in someEnumeration ?? Enumerable.Empty<MyType>()) { //some sensible thing to do on element... didSomething = true; } if(!didSomething) { //handle the fact that it was null or empty (without caring which). }

Del mismo modo (someEnumeration ?? Enumerable.Empty<MyType>()).ToList() etc.


Uniendo las respuestas anteriores en un método de extensión simple para C # 6.0+:

public static bool IsNullOrEmpty<T>(this IEnumerable<T> me) => !me?.Any() ?? true;


nada en el marco, pero es un método de extensión bastante directo.

Mira aquí

/// <summary> /// Determines whether the collection is null or contains no elements. /// </summary> /// <typeparam name="T">The IEnumerable type.</typeparam> /// <param name="enumerable">The enumerable, which may be null or empty.</param> /// <returns> /// <c>true</c> if the IEnumerable is null or empty; otherwise, <c>false</c>. /// </returns> public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable) { if (enumerable == null) { return true; } /* If this is a list, use the Count property for efficiency. * The Count property is O(1) while IEnumerable.Count() is O(N). */ var collection = enumerable as ICollection<T>; if (collection != null) { return collection.Count < 1; } return !enumerable.Any(); }

Daniel Vaughan da el paso extra de lanzar a ICollection (donde sea posible) por motivos de rendimiento. Algo que no hubiera pensado hacer.


Actualización tardía : desde C # 6.0, el operador de propagación nula se puede usar para expresar concisión como esta:

if (enumerable?.Any() ?? false)

Nota 1: ?? false ?? false es necesario, por el siguiente motivo (resumen / cita de esta publicación ):

?. el operador devolverá null si un miembro hijo es null . Pero [...] si intentamos obtener un miembro que no sea Nullable , como el método Any() , que devuelve bool [...] el compilador "ajustará" un valor de retorno en Nullable<> . Por ejemplo, Object?.Any() nos dará bool? (que es Nullable<bool> ), no bool . [...] Dado que no se puede convertir implícitamente en bool esta expresión no se puede usar en el if

Nota 2: como una bonificación, la declaración también es "thread-safe" (cita de la respuesta de esta pregunta ):

En un contexto multiproceso, si se puede acceder a [ enumerable ] desde otro subproceso (ya sea porque es un campo accesible o porque está cerrado en un lambda que está expuesto a otro subproceso), el valor podría ser diferente cada vez que se compute [ ieprior null -check ]


var nullOrEmpty = !( list?.Count > 0 );


var nullOrEmpty = list == null || !list.Any();