Si je comprends bien, dans Linq, la méthode FirstOrDefault()
peut renvoyer une Default
valeur autre que null. Ce que je n'ai pas déterminé, c'est quel genre de choses autres que null peuvent être retournées par cette méthode (et similaire) lorsqu'il n'y a aucun élément dans le résultat de la requête. Existe-t-il un moyen particulier de configurer cela de sorte que s'il n'y a pas de valeur pour une requête particulière, une valeur prédéfinie soit renvoyée comme valeur par défaut?
142
YourCollection.FirstOrDefault()
, vous pouvez utiliserYourCollection.DefaultIfEmpty(YourDefault).First()
par exemple.MyCollection.Last().GetValueOrDefault(0)
pour ça. Sinon, la réponse de @Jon Skeet ci-dessous est correcte pour l'OMI.Réponses:
Cas général, pas seulement pour les types valeur:
Encore une fois, cela ne peut pas vraiment dire s'il y avait quelque chose dans votre séquence ou si la première valeur était la valeur par défaut.
Si cela vous intéresse, vous pouvez faire quelque chose comme
et utiliser comme
bien que, comme le souligne M. Steak, cela pourrait être fait aussi bien par
.DefaultIfEmpty(...).First()
.la source
<T>
de leurs noms, mais le plus grave est quevalue == default(T)
cela ne fonctionne pas (car qui sait siT
peut être comparé pour l'égalité?)EqualityComparer<T>.Default.Equals(value, default(T))
pour éviter la boxe et éviter une exception si la valeur estnull
Non. Ou plutôt, il renvoie toujours la valeur par défaut pour le type d'élément ... qui est soit une référence nulle, la valeur nulle d'un type de valeur Nullable, ou la valeur naturelle "tous les zéros" pour un type valeur non Nullable.
Pour les types de référence, vous pouvez simplement utiliser:
Bien sûr, cela vous donnera également "l'autre valeur par défaut" si la première valeur est présente, mais est une référence nulle ...
la source
int
. Je préfère de beaucoup l'utilisation deDefaultIfEmpty
:src.Where(filter).DefaultIfEmpty(defaultValue).First()
. Fonctionne à la fois pour le type de valeur et le type de référence.Vous pouvez utiliser DefaultIfEmpty suivi de First :
la source
DefaultIfEmpty
- cela fonctionne avec les API ALL qui ont besoin d' un défaut à préciser:First()
,Last()
, etc. En tant qu'utilisateur, vous n'avez pas besoin de se rappeler que les API permettent de spécifier par défaut qui ne le font pas. Très élégant!À partir de la documentation de FirstOrDefault
À partir de la documentation par défaut (T) :
Par conséquent, la valeur par défaut peut être nulle ou 0 selon que le type est un type de référence ou de valeur, mais vous ne pouvez pas contrôler le comportement par défaut.
la source
Copié du commentaire de @sloth
Au lieu de
YourCollection.FirstOrDefault()
, vous pouvez utiliserYourCollection.DefaultIfEmpty(YourDefault).First()
par exemple.Exemple:
la source
DefaultIfEmpty
renvoie la valeur par défaut SI la collection est vide (contient 0 élément). Si vous utilisezFirst
WITH une expression correspondante comme dans votre exemple et que cette condition ne trouve aucun élément, votre valeur de retour sera vide.Vous pouvez également le faire
Cela utilise uniquement linq - yipee!
la source
FirstOrDefault
place deFirst
. Selon msdn.microsoft.com/en-us/library/bb340482.aspx , l'utilisation recommandée estFirst
En fait, j'utilise deux approches à éviter
NullReferenceException
lorsque je travaille avec des collections:Pour C # 6.0 ou version ultérieure:
Utilisez
?.
ou?[
pour tester si est null avant d'effectuer un accès membre à la documentation des opérateurs à condition nulleExemple:
var barCSharp6 = list.FirstOrDefault()?.Bar;
Ancienne version C #:
Utilisez
DefaultIfEmpty()
pour récupérer une valeur par défaut si la séquence est vide. Documentation MSDNExemple:
string barCSharp5 = list.DefaultIfEmpty(new Foo()).FirstOrDefault().Bar;
la source
Au lieu de
YourCollection.FirstOrDefault()
, vous pouvez utiliserYourCollection.DefaultIfEmpty(YourDefault).First()
par exemple.la source
Je viens d'avoir une situation similaire et je cherchais une solution qui me permette de renvoyer une valeur par défaut alternative sans m'en occuper du côté appelant à chaque fois que j'en ai besoin. Ce que nous faisons habituellement au cas où Linq ne prend pas en charge ce que nous voulons, c'est écrire une nouvelle extension qui s'en charge. C'est ce que j'ai fait. Voici ce que j'ai trouvé (pas testé cependant):
la source
Je sais que cela fait un moment mais j'ajouterai à cela, basé sur la réponse la plus populaire, mais avec une petite extension, j'aimerais partager ce qui suit:
Cela me permet de l'appeler en ligne comme tel avec mon propre exemple avec lequel j'avais des problèmes:
Donc, pour moi, je voulais juste qu'un résolveur par défaut soit utilisé en ligne, je peux faire ma vérification habituelle puis passer une fonction pour qu'une classe ne soit pas instanciée même si elle n'est pas utilisée, c'est une fonction à exécuter lorsque cela est nécessaire à la place!
la source
Utilisez à la
DefaultIfEmpty()
place deFirstOrDefault()
.la source