2009-08-26 7 views
66

est ici une version simplifiée de ce que je suis en train de faire:Comment puis-je faire en sorte que FirstOrDefault <KeyValuePair> a retourné une valeur

var days = new Dictionary<int, string>(); 
days.Add(1, "Monday"); 
days.Add(2, "Tuesday"); 
... 
days.Add(7, "Sunday"); 

var sampleText = "My favorite day of the week is 'xyz'"; 
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value)); 

Depuis « xyz » est pas présent dans la variable KeyValuePair, la La méthode FirstOrDefault ne renverra pas une valeur valide. Je veux être capable de vérifier cette situation mais je me rends compte que je ne peux pas comparer le résultat à "null" parce que KeyValuePair est une structure. Le code suivant est invalide:

if (day == null) { 
    System.Diagnotics.Debug.Write("Couldn't find day of week"); 
} 

Nous vous essayez de compiler le code, Visual Studio lance l'erreur suivante:

Operator '==' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<int,string>' and '<null>' 

Comment puis-je vérifier que FirstOrDefault a retourné une valeur valide?

+1

Vous avez un bug, mais je suppose que c'est une chose de copier-coller: jours n'est pas une liste, et vous ne pouvez pas utiliser ajouter sur KeyValuePair. – Kobi

+0

ooops ... vous avez raison, je tapais de la mémoire et j'ai évidemment fait une erreur. Merci de l'avoir signalé. – desautelsj

+0

C'était probablement: var days = new Dictionary (); –

Répondre

42

Ceci est la façon la plus claire et concise, à mon avis:

var matchedDays = days.Where(x => sampleText.Contains(x.Value)); 
if (!matchedDays.Any()) 
{ 
    // Nothing matched 
} 
else 
{ 
    // Get the first match 
    var day = matchedDays.First(); 
} 

Cela devient complètement autour de l'utilisation de substance étrange valeur par défaut pour struct.

+12

Problème avec ceci, est qu'il y a potentiel (selon l'implémentation) que les jours énumérables seront énumérés deux fois, ou pire, retournent des valeurs différentes entre les appels Any() et First() –

+0

@RayBooysen Un appel de ToArray ou ToList résout le problème et vous pouvez utiliser Count/Length et un indexeur. – Console

119

FirstOrDefault ne renvoie pas la valeur null, il renvoie default(T).
Vous devriez vérifier:

var defaultDay = default(KeyValuePair<int, string>); 
bool b = day.Equals(defaultDay); 

De MSDN - Enumerable.FirstOrDefault<TSource>:

default(TSource) if source is empty; otherwise, the first element in source.

Notes:

+11

+1, KeyValuePair est un type de valeur (struct), pas un type de référence (classe) ou un type de valeur NULL, il ne peut donc pas être nul. – Lucas

+0

merci, ça marche en effet! – desautelsj

+0

opérateur typeof manquant, mais encore +1 pour les bonnes choses –

1

Vous pouvez le faire à la place:

var days = new Dictionary<int?, string>(); // replace int by int? 
days.Add(1, "Monday"); 
days.Add(2, "Tuesday"); 
... 
days.Add(7, "Sunday"); 

var sampleText = "My favorite day of the week is 'xyz'"; 
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value)); 

puis:

if (day.Key == null) { 
    System.Diagnotics.Debug.Write("Couldn't find day of week"); 
} 
Questions connexes