Wartość domyślna dla KeyValuePair


392

Mam obiekt typu IEnumerable<KeyValuePair<T,U>> keyValueList, którego używam

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

Jak mogę sprawdzić, czy getResultjest to ustawienie domyślne, w przypadku gdy nie mogę znaleźć właściwego elementu?

Nie mogę sprawdzić, czy tak jest, nullczy nie, ponieważ KeyValuePairjest strukturą.


1
Oto podobne pytanie z kilkoma interesującymi odpowiedziami: stackoverflow.com/q/793897/323071
Andre Luus

2
Możesz także powiedzieć getResult.Key! = Null, aby sprawdzić, czy lista jest pusta, tak jakby to był klucz, zawsze będzie pusta
pengibot

3
@pengibot Zakłada, że ​​klucz jest zerowalny.
Justin Skiles,

Odpowiedzi:


542

Spróbuj tego:

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

albo to:

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

5
Możesz skorzystać z koncepcji opcji „nowa” tutaj, ale unikaj konieczności ponownego określania typu: if (getResult.Equals (Activator.CreateInstance (getResult.GetType ())))
kevinpo

3
myślę, że if (getResult.Equals(default))również działa
Simon

2
@ Simon nie nie. defaultrówna się zero. I default(KeyValuePair<T,U>)to rzeczywista KeyValuePair, która zawiera null, null. Sam tego doświadczyłem.
Yokovaski

100

Możesz utworzyć ogólną (i ogólną) metodę rozszerzenia, taką jak ta:

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

        return isDefault;
    }
}

Stosowanie:

// 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

Spróbuj tego:

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
Oczywiście działa to tylko wtedy, gdy nigdy (przypadkowo lub celowo) nie dodasz wartości null jako klucza. Ale powiedziałbym, że to prawda przez większość czasu, więc dobry pomysł. Jest to zdecydowanie sposób na łatwiejszą kontrolę niż większość kontroli tutaj.
neminem,

3
Tak długo, jak klucz jest zerowalny.
Uri Abramson,

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

Jedyną rzeczą jest to, że się nie kompiluje. Zamiast tego należy użyć znaku równości.
Tamas Ionut

8

Polecam więcej zrozumienia sposobu przy użyciu metody rozszerzenia:

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

A następnie użyj:

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

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

if(country.IsNull()){

}

7

Z oryginalnego kodu wygląda to tak, jakbyś chciał sprawdzić, czy lista była pusta:

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

Możesz po prostu pominąć pierwszą linię, ponieważ nie jest używana.
HeyJude

0

Aby uniknąć boksowania KeyValuePair.Equals(object), możesz użyć ValueTuple.

if ((getResult.Key, getResult.Value) == default)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.