11 comments on “Zapewniaj metodę ToString() w swoich obiektach

  1. Hm z mojej perspektywy takie podejście łamie jednak zasadę brzytwy Occam’a.

    Jeśli jakaś klasa potrzebuje metody ToString(), bo posługując się Twoim przykładem, chcemy wyświetlić jej obiekty w liście rozwijalnej to w porządku – dajmy jej tę metodę. Jeśli jednak ma to służyć wyłącznie debuggingowi to skłaniałbym się ku zaproponowanemu dalej DebuggerDisplyAttribute.

    Jeśli ktoś już upiera się przy nadpisywaniu metody ToString(), może użyć atrybutu [Conditional(„DEBUG”)]. W takim wypadku nadpisanie metody nastąpi wyłącznie w kodzie kompilowanym w konfiguracjach Debug.

    Więcej o metodach warunkowych: http://msdn.microsoft.com/en-us/library/aa288458(v=vs.71).aspx

  2. Bardzo fajnie opisane (chociaż nie cały świat używa TDD chciał bym zaznaczyć – czy się tego chce czy nie). O atrybucie DebugDisplay nie wiedziałem – pewnie pozwolę sobie też krótki post na moim blogu o nim popełnić (bardzo przydatna sprawa). Co do ToString() to jednak trzeba być bardzo ostrożnym bo to jest metoda wykorzystywana w automatyce nie tylko debuggera. Czasami domyślna metoda sortowania w jakichś kontrolkach to sortowanie po stringu z ToString() – ale czasem i w mniej oczywistych sytuacjach – wystarczy, że jakiś zewnętrzny komponent woła na dostarczonym elemencie ToString() – i teraz możemy sobie zaburzyć sortowanie lub też sprawić, że metoda ToString będzie wywoływana wielokrotnie zupełnie nie potrzebnie produkując stringi które zajmą dużo pamięci (a jak jeszcze komuś przyjdzie do głowy sklejanie stringów plusem to już brrr)

  3. Pingback: Handy DebuggerDisplay Attribute | DevYoda

  4. Co do combo boxa to sie nie zgodze. Zaraz bedziesz mial dugiego gdzie trzeba wyswietlic tylko imie i nazwisko, co wtedy? W jednym bedziesz mial .ToString(), a w drugim wrapper?

    Codo debugowania? Tez nie… przeciez nie bedziesz zmienial co chwile implementacji ToString() bo teraz inne pole chcesz widziec, a moze uzywasz juz go w comboboxie i wtedy skopiesz wyswietlanie?

    Co jak sobie ustawisz w ToString() wyswietlanie hasla (bo debugujesz hashowanie) zostawisz to, a ktos w logach bedzie wysweitlal info(„Nieudanie logowanie uzytkownika: {0}”, user);

    Moim zdaniej to przysparza wiecej bledow niz korzysci.

  5. Nadpisywanie ToString nie zawsze jest dobre, a implementacja przy pomocy string.Format może mieć skutki uboczne. Pierwszym z nich jest wywoływanie Geterów właściwości, które mogą zawierać logikę.
    Logika ta może nie być nawet widoczna w kodzie mając np. klasę faktury:

    class Invoice
    {
    public string Number { get; set; }
    public virtual Client Client { get; set; }
    // Other Properties

    public override string ToString()
    {
    return string.Format(„Invoice Number: {0}; From client: {1}”);
    }
    }

    i kawałek kodu zapisujący zamówienie:

    try
    {
    // saving Invoice
    }
    catch(SqlException e)
    {
    throw new RepoException(string.Format(„Error while saving invoice: {0}”, invoice), e);
    }

    może dojść do sytuacji w której wyjątek RepoException nie zostanie zgłoszony mimo zerwania połączenia z serwerem.
    Dzieje się tak ponieważ przy wirtualnej właściwości Client EF (albo inny maper) tworzy tymczasową klasę dziedziczącą po Client z implementacją właściwości, która zaciąga wartość „na żądanie”. Jeżeli połączenie z bazą zostało zamknięte i nie uda się go wznowić, to implementacja ta zgłosi nowy wyjątek, a informacje w oryginalnym wyjątku oraz wyjątku RepoException zostaną utracone. Jeszcze ciekawsze rzeczy się dzieją gdy wewnątrz implementacji właściwości znajduje się słówko lock.

    Z implementacji, którą przedstawiłeś można spokojnie używać gdy operujemy na POCO (np. DTO), albo na implementacjach wzorca ValueObject. Swoją drogą w przypadku ValueObject można zastosować dodatkową optymalizację polegającą na wyliczeniu wyniku toString w konstruktorze.

    Co do Comboboxów to posiadają one właściwości „DisplayMember”,”DisplayMemberPath”, albo ItemTemplate.

    Na koniec powiem, że sam używam ToStringa zawierającego string.Format żeby ułatwić sobie Debug albo na potrzeby ComboBoxów. Robię to głównie dlatego, że tak jest najłatwiej, a ryzyko wystąpienia negatywnych efektów o których pisałem jest w tych projektach nikłe. Warto jednak o nich wiedzieć.

  6. Pingback: Zapewniaj metodę ToString() w swoich obiektach – część 2 | Piotr Perak

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s