2009-08-26 9 views
66

Aquí hay una versión simplificada de lo que estoy tratando de hacer:¿Cómo me aseguro de que FirstOrDefault <KeyValuePair> ha devuelto un valor

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

Desde 'xyz' no está presente en la variable KeyValuePair, la El método FirstOrDefault no devolverá un valor válido. Quiero poder verificar esta situación, pero me doy cuenta de que no puedo comparar el resultado con "nulo" porque KeyValuePair es una estructura. El siguiente código es válido:

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

Le intento de compilar el código, Visual Studio lanza el siguiente error:

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

¿Cómo puedo comprobar que FirstOrDefault ha devuelto un valor válido?

+1

Usted tiene un error, pero supongo que es una cosa de copiar y pegar: días no es una lista, y no puedes usar add en KeyValuePair. – Kobi

+0

ooops ... está en lo correcto Estaba escribiendo de memoria y obviamente cometí un error. Gracias por mencionarlo. – desautelsj

+0

Probablemente fue: var days = new Dictionary (); –

Respuesta

42

Ésta es la manera más clara y concisa, en mi opinión:

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

Esto consigue por completo alrededor de usar cosas raras valor predeterminado de estructuras.

+12

Problema con esto, es que existe el potencial (dependiendo de la implementación) de que los días enumerables se enumerarán dos veces, o incluso peor, devolverán valores diferentes entre las llamadas Any() y First() –

+0

@RayBooysen Una llamada de ToArray o ToList resuelve el problema y puede usar Count/Length y un Indexer. – Console

119

FirstOrDefault no devuelve nulo, devuelve default(T).
, deberá verificar que:

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.

Notas:

+11

+1, KeyValuePair es un tipo de valor (struct), no un tipo de referencia (clase) o un tipo de valor que admite nulos, por lo que no puede ser nulo. – Lucas

+0

gracias, funciona realmente! – desautelsj

+0

operador typeof faltante, pero aún +1 para cosas buenas –

1

Usted puede hacer esto en su lugar:

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

y luego:

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