El valor predeterminado para KeyValuePair


392

Tengo un objeto del tipo IEnumerable<KeyValuePair<T,U>> keyValueList, estoy usando

 var getResult= keyValueList.SingleOrDefault();
 if(getResult==/*default */)
 {
 }
 else
 {
 } 

¿Cómo puedo verificar si getResultes el predeterminado, en caso de que no pueda encontrar el elemento correcto?

No puedo verificar si es nullo no, porque KeyValuePaires una estructura.


1
Aquí hay una pregunta similar con algunas respuestas interesantes: stackoverflow.com/q/793897/323071
Andre Luus

2
También puede decir getResult.Key! = Nulo para verificar si la lista es nula como si fuera la clave siempre será nula
pengibot

3
@pengibot Eso supone que la clave es anulable.
Justin Skiles

Respuestas:


542

Prueba esto:

if (getResult.Equals(new KeyValuePair<T,U>()))

o esto:

if (getResult.Equals(default(KeyValuePair<T,U>)))

55
Puede usar el concepto de la opción "nueva" aquí, pero evite tener que volver a especificar el tipo: if (getResult.Equals (Activator.CreateInstance (getResult.GetType ())))
kevinpo

3
Creo que if (getResult.Equals(default))también funciona
Simon

2
@ Simon no, no lo hace. defaultes igual a nulo Y default(KeyValuePair<T,U>)es un KeyValuePair real que contiene null, null. Experimenté esto yo mismo.
Yokovaski

100

Puede crear un método de extensión general (y genérico), como este:

public static class Extensions
{
    public static bool IsDefault<T>(this T value) where T : struct
    {
        bool isDefault = value.Equals(default(T));

        return isDefault;
    }
}

Uso:

// We have to set explicit default value '0' to avoid build error:
// Use of unassigned local variable 'intValue'
int intValue = 0;
long longValue = 12;
KeyValuePair<String, int> kvp1 = new KeyValuePair<String, int>("string", 11);
KeyValuePair<String, int> kvp2 = new KeyValuePair<String, int>();
List<KeyValuePair<String, int>> kvps = new List<KeyValuePair<String, int>> { kvp1, kvp2 };
KeyValuePair<String, int> kvp3 = kvps.FirstOrDefault(kvp => kvp.Value == 11);
KeyValuePair<String, int> kvp4 = kvps.FirstOrDefault(kvp => kvp.Value == 15);

Console.WriteLine(intValue.IsDefault()); // results 'True'
Console.WriteLine(longValue.IsDefault()); // results 'False'
Console.WriteLine(kvp1.IsDefault()); // results 'False'
Console.WriteLine(kvp2.IsDefault()); // results 'True'
Console.WriteLine(kvp3.IsDefault()); // results 'False'
Console.WriteLine(kvp4.IsDefault()); // results 'True'

27

Prueba esto:

KeyValuePair<string,int> current = this.recent.SingleOrDefault(r => r.Key.Equals(dialog.FileName) == true);

if (current.Key == null)
    this.recent.Add(new KeyValuePair<string,int>(dialog.FileName,0));

3
Por supuesto, eso solo funciona si nunca va a agregar (accidental o intencionalmente) nulo como clave. Pero diría que es cierto la gran mayoría de las veces, así que es una buena idea. Definitivamente es una verificación mucho más simple que la mayoría de las verificaciones aquí.
neminem

3
Mientras la clave sea anulable.
Uri Abramson

10
if(getResult.Key.Equals(default(T)) && getResult.Value.Equals(default(U)))

Lo único es que no se compila. Iguales deben usarse en su lugar.
Tamas Ionut

8

Recomiendo una forma más comprensiva usando el método de extensión:

public static class KeyValuePairExtensions
{
    public static bool IsNull<T, TU>(this KeyValuePair<T, TU> pair)
    {
        return pair.Equals(new KeyValuePair<T, TU>());
    }
}

Y luego solo usa:

var countries = new Dictionary<string, string>
{
    {"cz", "prague"},
    {"de", "berlin"}
};

var country = countries.FirstOrDefault(x => x.Key == "en");

if(country.IsNull()){

}

7

Desde su código original, parece que lo que quiere es verificar si la lista estaba vacía:

var getResult= keyValueList.SingleOrDefault();
if (keyValueList.Count == 0)
{
   /* default */
}
else
{
}

Puede omitir la primera línea, ya que no se usa.
HeyJude

0

Para evitar el boxeo de KeyValuePair.Equals(object)usted puede usar a ValueTuple.

if ((getResult.Key, getResult.Value) == default)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.