Próbowałem sprawdzić wartość null, ale kompilator ostrzega, że ten warunek nigdy nie wystąpi. Czego powinienem szukać?
Próbowałem sprawdzić wartość null, ale kompilator ostrzega, że ten warunek nigdy nie wystąpi. Czego powinienem szukać?
Odpowiedzi:
Zakładając, że chcesz uzyskać wartość wtedy, gdy klucz nie istnieje, należy użyć Dictionary<TKey, TValue>.TryGetValue
:
int value;
if (dictionary.TryGetValue(key, out value))
{
// Key was in dictionary; "value" contains corresponding value
}
else
{
// Key wasn't in dictionary; "value" is now 0
}
(Użycie, ContainsKey
a następnie indeksatora powoduje dwukrotne sprawdzenie klucza, co jest dość bezcelowe).
Należy pamiętać, że nawet jeśli były przy użyciu typów referencyjnych, sprawdzanie wartości null nie działa - Indexer dla Dictionary<,>
rzuci wyjątek, jeśli poprosisz brakującego klucza, zamiast wracać null. (To jest duża różnica między Dictionary<,>
a Hashtable
.)
ContainsKey
, co jest prawdą, ponieważ musi również wydobyć wartość. Nie robi to jednak dwóch wyszukiwań.
Słownik zgłasza KeyNotFound
wyjątek w przypadku, gdy słownik nie zawiera klucza.
Jak sugerowano, ContainsKey
jest to odpowiednie środki ostrożności. TryGetValue
jest również skuteczny.
Dzięki temu słownik może efektywniej przechowywać wartość null. Bez takiego zachowania sprawdzanie wyniku zerowego z operatora [] wskazywałoby albo wartość zerową, albo brak klucza wejściowego, co nie jest dobre.
Jeśli sprawdzasz tylko przed próbą dodania nowej wartości, użyj ContainsKey
metody:
if (!openWith.ContainsKey("ht"))
{
openWith.Add("ht", "hypertrm.exe");
}
Jeśli sprawdzasz, czy wartość istnieje, użyj TryGetValue
metody opisanej w odpowiedzi Jona Skeeta.
GetValueElseAdd
metody, którym podajesz wartość (lub a Func<TValue>
), aby również zapisać rozdzielczość we wkładce, jeśli zamierzasz dodać, jeśli jej tam nie ma. Domyślam się, że powodem, dla którego nie trafił do bibliotek .NET, jest to, że ścieżka dodawania jest rzadsza, jeśli używasz jej w stylu pamięci podręcznej]
TryGetValue
byłoby lepiej, ale jeśli chcesz sprawdzić, czy słownik zawiera klucz, aby uniknąć podwójnych dodatków, powiedziałbym, że ContainsKey
jest równie dobry (jeśli nie lepszy).
Powinieneś sprawdzić Dictionary.ContainsKey (int key) przed próbą wyciągnięcia wartości.
Dictionary<int, int> myDictionary = new Dictionary<int, int>();
myDictionary.Add(2,4);
myDictionary.Add(3,5);
int keyToFind = 7;
if(myDictionary.ContainsKey(keyToFind))
{
myValueLookup = myDictionay[keyToFind];
// do work...
}
else
{
// the key doesn't exist.
}
TryGetValue
. Na szczęście teraz tak, więc będę wiedział w przyszłości. Mam zamiar pozostawić tę odpowiedź bez zmian, chociaż dyskusja jest cenna.
TryGetValue
w wyrażeniu lambda. Chociaż to sprawia, że myślę, że nowe rozszerzenie C # byłoby catch
operatorem podobnym do null
operatora koalescencji.
Klasa pomocnicza jest przydatna:
public static class DictionaryHelper
{
public static TVal Get<TKey, TVal>(this Dictionary<TKey, TVal> dictionary, TKey key, TVal defaultVal = default(TVal))
{
TVal val;
if( dictionary.TryGetValue(key, out val) )
{
return val;
}
return defaultVal;
}
}
ContainsKey jest tym, czego szukasz.
Powinieneś prawdopodobnie użyć:
if(myDictionary.ContainsKey(someInt))
{
// do something
}
Powodem, dla którego nie możesz sprawdzić null, jest to, że klucz tutaj jest typem wartości.
int result= YourDictionaryName.TryGetValue(key, out int value) ? YourDictionaryName[key] : 0;
Jeśli klucz jest obecny w słowniku, zwraca wartość klucza, w przeciwnym razie zwraca 0.
Mam nadzieję, że ten kod ci pomoże.
TryGetValue
wystarczy, użyj value
zamiastresult
Rozważ opcję hermetyzacji tego konkretnego słownika i podaj metodę zwracania wartości dla tego klucza:
public static class NumbersAdapter
{
private static readonly Dictionary<string, string> Mapping = new Dictionary<string, string>
{
["1"] = "One",
["2"] = "Two",
["3"] = "Three"
};
public static string GetValue(string key)
{
return Mapping.ContainsKey(key) ? Mapping[key] : key;
}
}
Następnie możesz zarządzać zachowaniem tego słownika.
Na przykład tutaj: jeśli słownik nie ma klucza, zwraca klucz, który przekazujesz przez parametr.