SingleOrDefault renvoie null, mais que se passe-t-il si je veux attribuer des valeurs pour représenter l'objet qui n'a pas été trouvé?
Réponses
Trop de publicités??? opérateur . Si l'argument de gauche est nul, évaluez et renvoyez le deuxième argument.
myCollection.SingleOrDefault() ?? new[]{new Item(...)}
Cela ne fonctionnera qu'avec les types de référence (ou nullables), mais cela fera ce que vous recherchez très simplement.
Vous pouvez rouler le vôtre.
public static T SingleOrDefault<T>(this IEnumerable<T> enumerable, T defaultValue) {
if ( 1 != enumerable.Count() ) {
return defaultValue;
}
return enumerable.Single();
}
Cela peut être un peu cher car Count () vous oblige à traiter la collection entière et peut être assez coûteux à exécuter. Il serait préférable d'appeler Single, d'intercepter l'InvalidOperationException ou de lancer une méthode IsSingle
public static bool IsSingle<T>(this IEnumerable<T> enumerable) {
using ( var e = enumerable.GetEnumerator() ) {
return e.MoveNext() && !e.MoveNext();
}
}
public static T SingleOrDefault<T>(this IEnumerable<T> enumerable, T defaultValue) {
if ( !enumerable.IsSingle() ) {
if( enumerable.IsEmpty() ) {
return defaultValue;
}
throw new InvalidOperationException("More than one element");
}
return enumerable.Single();
}
Vous pouvez créer vos propres méthodes d'extension - SingleOrNew.
public static class IEnumerableExtensions
{
public static T SingleOrNew<T>( this IEnumerable<T> enumeration, T newValue )
{
T elem = enumeration.SingleOrDefault();
if (elem == null)
{
return newValue;
}
return elem;
}
public static T SingleOrNew<T>( this IEnumerable<T> enumeration, Func<T,bool> predicate, T newValue )
{
T elem = enumeration.SingleOrDefault( predicate );
if (elem == null)
{
return newValue;
}
return elem;
}
}