La valeur par défaut pour KeyValuePair

392

J'ai un objet du type IEnumerable<KeyValuePair<T,U>> keyValueList, j'utilise

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

Comment puis-je vérifier si getResultc'est la valeur par défaut, au cas où je ne trouverais pas l'élément correct?

Je ne peux pas vérifier si c'est le cas null, car KeyValuePairc'est une structure.

Graviton
la source
1
Voici une question similaire avec des réponses intéressantes: stackoverflow.com/q/793897/323071
Andre Luus
2
Vous pouvez également dire getResult.Key! = Null pour vérifier si la liste est nulle comme si c'était la clé sera toujours nulle
pengibot
3
@pengibot Cela suppose que la clé peut être annulée.
Justin Skiles

Réponses:

542

Essaye ça:

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

ou ca:

if (getResult.Equals(default(KeyValuePair<T,U>)))
Andrew Hare
la source
5
Vous pouvez utiliser ici le concept de la "nouvelle" option, mais évitez de devoir spécifier à nouveau le type: if (getResult.Equals (Activator.CreateInstance (getResult.GetType ())))
kevinpo
3
je pense que if (getResult.Equals(default))ça marche aussi
Simon
2
@Simon non, ce n'est pas le cas. defaultest égal à null. Et default(KeyValuePair<T,U>)est un KeyValuePair réel qui contient null, null. J'ai vécu cela moi-même.
Yokovaski
100

Vous pouvez créer une méthode d'extension générale (et générique), comme celle-ci:

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

        return isDefault;
    }
}

Usage:

// 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'
pholpar
la source
27

Essaye ça:

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));
Peter
la source
3
Bien sûr, cela ne fonctionne que si vous n'allez jamais (accidentellement ou délibérément) ajouter null comme clé. Mais je dirais que c'est vrai la grande majorité du temps, donc bonne idée. C'est certainement une vérification beaucoup plus simple que la plupart des vérifications ici.
neminem
3
Tant que la clé est nullable.
Uri Abramson
10
if(getResult.Key.Equals(default(T)) && getResult.Value.Equals(default(U)))
ChaosPandion
la source
La seule chose est qu'il ne compile pas. Des égaux doivent être utilisés à la place.
Tamas Ionut
8

Je recommande une manière plus compréhensive d'utiliser la méthode d'extension:

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

Et puis utilisez simplement:

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

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

if(country.IsNull()){

}
Miroslav Holec
la source
7

À partir de votre code d'origine, il semble que vous souhaitiez vérifier si la liste était vide:

var getResult= keyValueList.SingleOrDefault();
if (keyValueList.Count == 0)
{
   /* default */
}
else
{
}
Stephen Westlake - Infusion
la source
Vous pouvez simplement omettre la première ligne, car elle n'est pas utilisée.
HeyJude
0

Pour éviter la boxe de KeyValuePair.Equals(object)vous pouvez utiliser un ValueTuple.

if ((getResult.Key, getResult.Value) == default)
Jonas Nyrup
la source