Lors de l'appel de Any () sur un objet nul, il lève une ArgumentNullException en C #. Si l'objet est nul, il n'y en a certainement pas, et il devrait probablement retourner faux.
Pourquoi C # se comporte-t-il de cette façon?
Lorsqu'il s'agit de types de référence, une valeur null
est sémantiquement différente d'une valeur "vide".
Une chaîne null
n'est pas la même chose que string.Empty
, et un null
IEnumerable<T>
n'est pas la même chose que Enumerable.Empty<T>
(ou tout autre énumérable "vide" de ce type).
Si Any
n'était pas une méthode d'extension, l'appeler sur null
entraînerait NullReferenceException
. Puisqu'il est une méthode d'extension, lever une exception (bien que non nécessaire) est une bonne idée car elle préserve la sémantique bien connue d'essayer d'appeler un méthode sur null
: BOOM!
Any()
demande: "Cette boîte contient-elle des éléments?"
Si la case est vide, la réponse est clairement non.
Mais s'il n'y a pas de boîte en premier lieu, alors la question n'a aucun sens, et la fonction se plaint: "De quoi parlez-vous? Il n'y a pas de boîte."
Avec le C # moderne, vous pouvez facilement gérer le scénario de l'OP avec une simple vérification comme celle-ci:
List<string> foo = null;
if (foo?.Any() ?? false)
{
DoStuff();
}
C'est un peu comme une implémentation boiteuse de AnyOrDefault(bool default)
que l'OP attend de la méthode d'extension Any()
.
Vous pouvez facilement en faire une extension comme celle-ci:
public static bool HasItems<T>(this IEnumerable<T> source)
{
return (source?.Any() ?? false);
}
Honnêtement, je n'aime pas vraiment le nom Renommé en AnyOrDefault
pour cela car cela n'aura jamais de sens de passer une valeur par défaut (une valeur par défaut true serait probablement assez méchante pour les personnes qui liront du code plus tard).HasItems
, comme suggéré dans les commentaires. C'est un bien meilleur nom!
Any()
est une méthode d'extension, donc this
est en fait passé comme premier argument à la méthode. Dans cette situation, il est compréhensible qu'il lance ArgumentNullException
is this
is null
.
Vous pouvez effectuer le contrôle vous-même au préalable:
bool hasAny = yourData == null ? false : yourData.Any(yourPredicate);
Parce que Any () c'est une méthode d'extension comme celle-ci:
public static bool Any(this IEnumerable enumerable)
{
if (enumerable == null)
throw ArgumentNullException("enumerable");
...
}
La méthode Any
s'exécute sur un IEnumerable
et vous indique s'il existe des éléments dans l'énumérable. Si vous ne lui donnez rien à énumérer, une ArgumentNullException est raisonnable: une collection sans élément (correspondant) est différente de no collecion.
Comme d'autres l'ont déjà mentionné, Any
vérifie si une séquence contient ou non des éléments. Cela ne vous empêche pas de passer des valeurs null
(quel pourrait être le bogue en premier lieu).
Chaque méthode d'extension dans la classe Enumerable
lance un ArgumentNullException
si le source
est null
. Lancer ArgumentNullExceptions
dans les extensions est en fait bonne pratique .