2009-08-26 8 views
66

Oto uproszczona wersja tego, co próbuję zrobić:Jak mogę się upewnić, że FirstOrDefault <KeyValuePair> powrócił wartość

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)); 

Ponieważ „xyz” nie jest obecna w zmiennej KeyValuePair The Metoda FirstOrDefault nie zwróci poprawnej wartości. Chcę być w stanie sprawdzić tę sytuację, ale zdaję sobie sprawę, że nie mogę porównać wyniku z wartością "null", ponieważ KeyValuePair jest strukturą. Poniższy kod jest nieprawidłowy:

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

Mamy próbie kompilacji kodu, Visual Studio generuje następujący błąd:

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

Jak mogę sprawdzić, czy FirstOrDefault powrócił prawidłową wartość?

+1

Masz problem istnieje, ale zakładam, że to copy-paste rzecz: dzień nie jest to lista, a nie możesz używać dodatku KeyValuePair. – Kobi

+0

ooops ... masz rację, pisząc z pamięci i oczywiście popełniłem błąd. Dziękuję za wskazanie. – desautelsj

+0

To było prawdopodobnie: var days = new Dictionary (); –

Odpowiedz

42

Jest to najbardziej jasny i zwięzły sposób moim zdaniem:

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

Ten całkowicie omija za pomocą wartości domyślnej dziwne rzeczy na elemencie.

+12

Problem z tym, że istnieje potencjał (w zależności od implementacji), że dni przeliczalne będą wyliczane dwa razy lub, co gorsza, zwracają różne wartości między wywołaniami Any() i First() –

+0

@RayBooysen A ToArray lub ToList rozwiązuje problem i możesz użyć Count/Length i Indexer. – Console

119

FirstOrDefault nie zwraca wartości null, zwraca default(T).
Należy sprawdzić:

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

Od MSDN - Enumerable.FirstOrDefault<TSource>:

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

Uwagi:

+11

+1, KeyValuePair to typ wartości (struct), a nie typ odwołania (klasa) lub typ wartości zerowej, więc nie może mieć wartości null. – Lucas

+0

dzięki, to naprawdę działa! – desautelsj

+0

Brak operatora typeof, ale wciąż +1 za dobre rzeczy –

1

Można to zrobić w zamian:

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)); 

a następnie:

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