Code review: bezpieczny dostęp do słownika

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.

7 thoughts on “Code review: bezpieczny dostęp do słownika”

  1. 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 🙂

  2. 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.

  3. 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.

  4. 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 😛

Leave a Reply

Your email address will not be published.