Wizualizacja obiektów w debuggerze (DebuggerVisualizers)

Niedawno oglądałem nagranie z sesji Advanced Debugging with Visual Studio 2010, która prowadził Ingo Rammer. Bardzo fajna sesja, świetnie prowadzona. Pojawiły się na niej ciekawe informacje, które pozwalają ułatwić i urozmaicić sobie sesje w debuggerze Visual Studio. Zainspirowany tematem, postanowiłem na własnej skórze przetestować pokazywane rozwiązania.

Poprzednio pokazywałem jak można manipulować wyświetlaniem informacji o obiektach naszych klas (przeciążanie metody ToString() i/lub użycie atrybutu DebuggerDisplay). Dzisiaj pokażę jak stworzyć własny edytor (visualizer) do edycji obiektów naszych klas podczas debugowania (przykład ten nie był w całości pokazany w sesji Ingo Rammera.

Debugowanie po staremu

Załóżmy, że mamy prostą klasę Person. Cztery właściwości i przeciążona metoda ToString.

Gdy utworzymy obiekt klasy Person, a następnie podczas debugowania chcemy zobaczyć stan naszego obiektu to użyjemy okienek Autos, Watch, Locals.

Można też najechać kursorem myszki na obiekt i pokawi się „podręczny pop-up z informacjami o obiekcie”

W tym miejscu chciałbym zwrócić szczególną uwagę na właściwości FirstName oraz LastName obiektu john, ponieważ podręczny pop-up ukazuje ikonki z lupą. Jest to właśnie DebuggerVisualizer dla typu string. Przydaje się on, gdy string jest bardzo długi (wielowierszone zapytanie SQL) albo gdy chcemy zobaczyć XML’a. Okazuje się, że możemy takie coś zrobić dla całego typu Person! Do dzieła.

How to

Aby zrobić własny Visualizer potrzebujemy:

  • Własne okno do wizualizacji
  • Odpowiednią  referencję
  • Dodatkowa klasa, która obsługuje wizualizację
  • Drobna modyfikacja klasy Person

Własne okno do wizualizacji

Dodaj do projektu nowy element – Windows Form (niech się nazywa PersonDebugVisualizerForm. Na formularzu umieszczamy kontrolki, za pomocą których chcemy wyświetlać i modyfikować składowe klasy Person.

W tym przykładzie ustawiłem TextBoxy i DateTimePicker jako publiczne, aby było prościej (oczywiście można tutaj dowolną technikę zastosować). Cancel zamyka okno. Klawisz OK ustawia DialogResult na OK i również zamyka okno.

Referencje

Dodajemy do naszego projektu referencję do Microsoft.VisualStudio.DebuggerVisualizers.

Obsługa wizualizera

Teraz musimy powiedzieć Visual Studio, że mamy specjalny formularz do wizualizacji (przy okazji też do edycji) klasy Person. W tym celu utwórz nową klasę o nazwie PersonVisualizer. Klasa musi dziedziczyć po DialogDebuggerVisualizer (jest to bazowa, abstrakcyjna klasa do wizualizacji). Implementujemy jedną metodę Show. Show jest wywoływane w chwili, gdy podczas debugowania zostanie naciśnieta ikona z lupą. A więc potrzebujemy aby pojawił się nasz formularz i wypełnił danymi z obiektu. Pełny kod klasy PersonVisualizer poniżej:

Klasa Person

Ostatnia rzecz to dodanie atrybutów Serializable oraz DebuggerVisualizer do obiektu Person. Obiekt, który na podlegać wizualizacji musi się dać serializować, gdyż inaczej nie można go przekazać do wizualizera. Z kolei DebuggerVisualizer mówi jaki wizualizer obsługuje klasę Person (w tym przypadku jest to stworzona we wcześniejszym punkcie klasa PersonVisualizer).

Test

Pozostaje przetestować rozwiązanie. Utwórz obiekt klasy Person, sprawdź debuggerzem stan obiektu, zobaczysz nową ikonę z lupą.

Naciśnij ikonę z lupą, powinna się pojawić nasza nowa unikatowa formatka wypełniona szczegółami obiektu.

Zmień wartości, a po naciśnięciu OK zobaczysz, że obiekt został zaktualizowany.

Podsumowanie

Możliwości są ogromne, możemy wywołać dowolny kod. Nie trzeba się ograniczać do prostej formatki edycyjnej. Można budować ciekawe diagramy, grafy, listy. Ograniczeniem jest tylko wyobraźnia.

Problemem (niestety, dość poważnym) jest sens 🙂 Bo tracić czas na tworzenie wymyślnych formularzy, tylko po to, aby ładnie wyglądało w debuggerze? Chyba nie. Dlatego traktuję to bardziej jako ciekawostkę.

Ale.. jeśli mamy w projektach coś co jest bardzo ważne i trudne do debugowania, wizualizacja mogła by się przydać (tak jak fabryczne wielo-wierszowe stringi, XML, czy zapytania SQL). Wówczas pewnie warto zainwestować trochę czasu, a debugowanie na pewno będzie przyjemniejsze.

Reklamy

4 thoughts on “Wizualizacja obiektów w debuggerze (DebuggerVisualizers)

  1. Pingback: dotnetomaniak.pl

  2. Jeśli chodzi o sens to w prostych przykładach to go nie ma :). W swojej karierze (heh jak to brzmi) jednak widziałem sensowny przypadek. Formatka prezentowała dane wektorowe, macierzowe itp. I nie tylko je wyświetlała ale pozwalała porównać. Nieocenione jest gdy ma się komunikat, że macierz 162×20 elementów jest identyczna do tej w zewnętrznym systemie. Jeśli ktoś nie wierzy polecam sprawdzać wartość po wartości ręcznie. Dokładność 9 miejsc po przecinku 🙂

    Pozdrawiam,
    Paweł

  3. W wiekszosci przypadkow uzycie tego ficzera rzeczywiscie mija sie z celem jednak jezeli w kodzie czesto i gesto wykorzystujemy jakas klase o zlozonej strukturze (np drzewiastej albo zlozonej z kilku poziomow kolekcji) to napisanie okienka zdecydowanie bedzie trwalo krocej niz walka z ciagle zamykajacym sie watchem.

  4. Pingback: Ukrywanie składowych klas w debuggerze (DebuggerBrowsable) | Wojciech Poniatowski

Możliwość komentowania jest wyłączona.