Je sais que la liste généralement vide est plus préférable que NULL. Mais je vais retourner NULL, principalement pour deux raisons
??
par la suite pour obtenir une valeur de retour.Pour les chaînes, nous avons IsNullOrEmpty. Y at-il quelque chose de C # lui-même faire la même chose pour List ou IEnumerable?
rien dans le cadre, mais c'est une méthode d'extension assez simple.
/// <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 fait un pas de plus vers le casting chez ICollection (si possible) pour des raisons de performances. Quelque chose que je n'aurais pas pensé faire.
Late update: depuis C # 6.0, le opérateur de propagation nul peut être utilisé pour exprimer de manière concise comme ceci:
if (enumerable?.Any() ?? false)
Note 1:?? false
est nécessaire pour la raison suivante (résumé/citation de cet article ):
?.
L'opérateur retourneranull
si un membre enfant estnull
. Mais si [...] nous essayons d'obtenir un membre non -Nullable
, comme le La méthodeAny()
, qui retournebool
[...] le compilateur aura "encapsuler" une valeur de retour dansNullable<>
. Par exemple,Object?.Any()
will donnez-nousbool?
(qui estNullable<bool>
), pasbool
. [...] Puisqu'elle ne peut pas être implicitement convertie enbool
, cette expression ne peut pas être utilisée dans laif
Note 2: en prime, la déclaration est également "thread-safe" (citation tirée de la réponse de cette question ):
Dans un contexte multithread, si [enumerable] est accessible à partir d'un autre thread (soit parce que c'est un champ accessible, soit parce que fermé dans un lambda exposé à un autre thread), puis le la valeur peut être différente chaque fois qu'il est calculé [i.e.prior null-check} _]
Il n'y a rien intégré.
C'est une méthode d'extension simple cependant:
public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
{
if(enumerable == null)
return true;
return !enumerable.Any();
}
var nullOrEmpty = list == null || !list.Any();
Rassembler les réponses précédentes en une méthode d'extension simple pour C # 6.0+:
public static bool IsNullOrEmpty<T>(this IEnumerable<T> me) => !me?.Any() ?? true;
Comme tout le monde l’a dit, rien n’est intégré dans le cadre, mais si vous utilisez Castle, Castle.Core.Internal l’a.
using Castle.Core.Internal;
namespace PhoneNumbers
{
public class PhoneNumberService : IPhoneNumberService
{
public void ConsolidateNumbers(Account accountRequest)
{
if (accountRequest.Addresses.IsNullOrEmpty()) // Addresses is List<T>
{
return;
}
...
Si vous devez pouvoir extraire tous les éléments s'il n'est pas vide, certaines des réponses fournies ne fonctionneront pas car l'appel à Any()
sur un énumérable non réenroulable "oubliera" un élément.
Vous pouvez adopter une approche différente et transformer les valeurs nulles en vides:
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).
}
De même, (someEnumeration ?? Enumerable.Empty<MyType>()).ToList()
etc. peuvent être utilisés.
var nullOrEmpty = !( list?.Count > 0 );
pour moi, la meilleure méthode isNullOrEmpty ressemble à ceci
public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
{
return !enumerable?.Any() ?? true;
}
J'ai modifié la suggestion de Matthew Vines pour éviter le "problème de dénombrement multiple possible de IEnumerable" - problème . (Voir aussi le commentaire de Jon Hanna)
public static bool IsNullOrEmpty(this IEnumerable items)
=> items == null
|| (items as ICollection)?.Count == 0
|| !items.GetEnumerator().MoveNext();
... et le test unitaire:
[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());
}