Często widzę następujący kod:
private Dictionary<string,string> _dictionary=new Dictionary<string, string>(); //...... string value = _dictionary["Key"];
Oczywiście jeśli mamy pewność, że zawsze jest klucz nie ma z tym problemu. Czasami jednak takiej pewności nie ma i należy zwrócić NULL albo stworzyć dany element w słowniku. Wtedy zaczynają się problemy bo najczęściej jest to dokonywane za pomocą:
if (_dictionary.ContainsKey("Key")) return _dictionary["Key"]; //else return null;
Powyższy kod będzie musiał dwa razy dokonać przeszukiwania słownika. Raz aby wykonać ContainsKey a potem drugi raz aby zwrócić element. Łączna złożoność to O(2). Jest to czas optymistyczny ponieważ gdy występują kolizje wtedy proces się wydłuża. Szybszym i lepszym rozwiązaniem jest użyte metody TryGetValue:
string value; _dictionary.TryGetValue("Key", out value);
Złożoność wynosi O(1). TryGetValue sprawdza czy klucz istnieje, jeśli tak to zwraca jego wartość w przeciwnym wypadku value wynosi NULL. W przeciwieństwie do zwykłego dostępu nie jest wyrzucany wyjątek. Jeśli zatem w pętli (np. w pętli renderującej) musimy dokonywać częstych operacji na słowniku to różnica między O(1) a O(2) ma już znaczenie bo w końcu może to być O(5000) a O(10000) – dwukrotnie szybsze rozwiązanie.
Fajna podpowiedź. Dzięki, na pewno się przyda.
dobrze wiedzieć, zawsze używałem pierwszego podejścia :/
Wiem, że nie w tym leży sedno wpisu, ale jeśli uważamy, że klucz POWINIEN w tym słowniku być obecny, to chyba lepiej od razu się wysypać, niż zwrócić null i dostać “Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu” trzy ramki dalej 🙂
Oo, dobrze wiedzieć, bo też popełniałem ten sam błąd.
Konrad dobrze pisze. Jezeli ktos najpierw sprawdza czy klucz jest i potem pobiera wartosc to calosc ma zle zorganizowana. Konstrukcja:
if (_dictionary.ContainsKey(“Key”))
return _dictionary[“Key”];
jest bledna z definicji.
Konrad pisze o innym przypadku i jak najbardziej ma racje. A konstrukcja nie jest zła – często trzeba zwrócić domyślną wartość jaką jest NULL. Czasami z kolei stworzyć nowy klucz z jakąś wartością jeśli takowy jeszcze nie istnieje.
Konrad z kolei piszę aby unikać wyjątków NULL reference i to prawda bo kod z takimi wyjątkami jest ciężki w utrzymaniu.
I tak źle i tak nie dobrze 🙂
Zupełnie jak kwestia czy (i kiedy o ile w ogóle) korzystać z wyjątków 😛
Ilu koderów tyle opcji 😛