🔥 Zapisy zamknięte, ale możesz pobrać Roadmapę .NET i dołączyć do listy oczekujących — Pobierz i dołącz do Listy VIP →

Debugowanie w C# — breakpointy i watch

Debugowanie w C# w Visual Studio — breakpointy i watch, grafika

Zamiast teorii — konkretny błąd i konkretne narzędzia Visual Studio, które pomogą go znaleźć.

Błąd, który znajdziemy

static double ObliczSrednia(List<int> oceny)
{
    int suma = 0;
    for (int i = 0; i <= oceny.Count; i++) // błąd: <= zamiast <
    {
        suma += oceny[i];
    }
    return suma / oceny.Count;
}

Wywołanie ObliczSrednia(new List<int> { 5, 4, 3 }) rzuci IndexOutOfRangeException. Zamiast zgadywać, gdzie jest problem, przejdźmy przez proces debugowania krok po kroku.

Breakpoint — F9

Kliknij na lewym marginesie linijki suma += oceny[i]; (albo ustaw kursor na tej linii i naciśnij F9) — pojawi się czerwona kropka. Uruchom program w trybie debugowania (F5). Program zatrzyma się na tej linii, zanim się wykona, dając Ci pełny podgląd stanu programu w tym dokładnym momencie.

Step Over, Step Into, Step Out

Trzy podstawowe klawisze do poruszania się po zatrzymanym programie:

  • F10 (Step Over) — wykonaj bieżącą linię i przejdź do następnej, nie wchodząc do wywoływanych metod. Używaj, gdy ufasz, że dana metoda działa poprawnie.
  • F11 (Step Into) — wykonaj bieżącą linię, ale jeśli wywołuje metodę, wejdź do jej wnętrza. Używaj, gdy podejrzewasz błąd wewnątrz tej metody.
  • Shift+F11 (Step Out) — dokończ wykonanie bieżącej metody i wróć do miejsca, skąd została wywołana. Używaj, gdy wszedłeś za głęboko i chcesz wrócić wyżej.

W naszym przykładzie naciskaj F10 kilka razy, obserwując wartość i — zobaczysz, że pętla próbuje wykonać się dla i == oceny.Count (czyli 3), a oceny[3] nie istnieje w liście trzyelementowej (indeksy 0, 1, 2).

Watch, Locals, Autos — podgląd zmiennych na żywo

Gdy program jest zatrzymany na breakpoincie, w dolnym panelu Visual Studio masz trzy okna:

  • Locals — automatycznie pokazuje wszystkie zmienne lokalne w bieżącym zasięgu (tutaj: oceny, suma, i).
  • Watch — dodajesz konkretne wyrażenie ręcznie (np. oceny.Count albo oceny[i]), żeby śledzić je przez cały czas debugowania, nawet gdy zmienia się kontekst.
  • Autos — pokazuje zmienne użyte w bieżącej i poprzedniej linii — dobre do szybkiego podglądu bez ręcznego dodawania.

Dodaj oceny.Count i i do Watch — zobaczysz w czasie rzeczywistym, że i dochodzi do 3, podczas gdy oceny.Count wynosi 3 — a warunek pętli i <= oceny.Count pozwala i osiągnąć wartość równą długości listy, co jest o jeden za dużo.

Warunkowy breakpoint — zatrzymaj się tylko wtedy, gdy to ma sens

Dla pętli wykonującej się setki razy, ręczne klikanie F10 aż do interesującego Cię przypadku jest stratą czasu. Kliknij prawym przyciskiem na breakpoint → Warunki (Conditions) → wpisz np. i == 3. Program zatrzyma się tylko wtedy, gdy i osiągnie tę wartość — pomijając wszystkie wcześniejsze, poprawne iteracje.

Break on exception — łap wyjątek w miejscu, gdzie faktycznie powstaje

Domyślnie program zatrzymuje się dopiero tam, gdzie wyjątek jest obsłużony (albo w ogóle się wywala, jeśli nikt go nie obsłużył) — niekoniecznie tam, gdzie powstał. W menu Debug → Windows → Exception Settings (albo Ctrl+Alt+E) zaznacz Common Language Runtime Exceptions. Teraz Visual Studio zatrzyma program dokładnie w linii suma += oceny[i];, w momencie rzucenia wyjątku — zamiast gdzieś dalej w stosie wywołań, gdzie kontekst oryginalnego błędu już częściowo zniknął.

Call Stack — jak tu trafiłeś

Okno Call Stack pokazuje pełną ścieżkę wywołań, które doprowadziły do bieżącej linii — który kod wywołał ObliczSrednia, a ten z kolei co wywołał wcześniej. Dla błędów głęboko zagnieżdżonych w wielowarstwowej aplikacji to często szybszy sposób zrozumienia kontekstu niż przechodzenie krok po kroku od samego początku programu.

Poprawka

static double ObliczSrednia(List<int> oceny)
{
    int suma = 0;
    for (int i = 0; i < oceny.Count; i++) // poprawione: < zamiast <=
    {
        suma += oceny[i];
    }
    return suma / (double)oceny.Count; // dodatkowo: rzutowanie na double, żeby uniknąć dzielenia całkowitoliczbowego
}

Dwa błędy w jednej metodzie: <= zamiast < (błąd o jeden za dużo) oraz dzielenie całkowitoliczbowe (suma / oceny.Count obcięłoby wynik do liczby całkowitej, np. 4/3 = 1 zamiast 1.33) — oba wykryte tym samym procesem: breakpoint, obserwacja zmiennych, zrozumienie dlaczego wartość jest inna niż oczekiwana.

Kiedy debugger nie wystarczy — logowanie

Dla błędów, które pojawiają się tylko w produkcji (nie da się podłączyć debuggera na żywo do serwera klienta), albo dla błędów zależnych od czasu (race conditions, gdzie zatrzymanie programu na breakpoincie zmienia jego zachowanie), jedynym praktycznym narzędziem pozostaje logowanie — Debug.WriteLine podczas developmentu, a w produkcji ustrukturyzowane logi (Serilog, ILogger). Debugger i logi to nie konkurencyjne narzędzia — pierwszy jest lepszy do “namierz błąd na własnej maszynie teraz”, drugi do “zrozum, co się stało w systemie, którego nie masz przed sobą”.

Podsumowanie

Debugowanie w Visual Studio to konkretny zestaw narzędzi, nie intuicja: breakpoint (F9) zatrzymuje program w wybranym miejscu, F10/F11/Shift+F11 pozwalają poruszać się po kodzie z kontrolą nad tym, czy wchodzisz do wywoływanych metod, okna Watch/Locals/Autos pokazują wartości zmiennych na żywo, warunkowy breakpoint oszczędza czas przy pętlach i wielokrotnych wywołaniach, a Exception Settings łapie wyjątek dokładnie tam, gdzie powstaje, zamiast tam, gdzie został obsłużony. Ten sam zestaw kroków — ustaw breakpoint, obserwuj zmienne, zawężaj obszar — działa niezależnie od tego, czy błąd jest banalny, czy ukryty głęboko w wielowarstwowej aplikacji.

Powiązane: podstawy stojące za błędami poznasz w obsłudze błędów w C# i wpisie o NullReferenceException. Na produkcji zamiast debuggera masz logi (ILogger, Serilog).

👨‍💻
Mariusz Jurczenko
Senior .NET Developer · 10+ lat doświadczenia komercyjnego

Programista .NET z doświadczeniem komercyjnym w firmach takich jak NFZ, Kamsoft, Diagnostyka, Hermes Reply Polska czy Etisoft Smart Solutions. Twórca kursów, z których skorzystało już ponad 11 000 osób w Strefie Kursów i ponad 1 000 kursantów na dev-hobby.pl.

Specjalizacja: Clean Code, Clean Architecture i uczenie programowania tak, żeby dało się je naprawdę zrozumieć — nie wykuć.

🚀 Co dalej?

Zobacz to w praktyce na wideo i pobierz darmową roadmapę, żeby ułożyć naukę w spójną ścieżkę do pierwszej pracy.

czytanie to początek

Zamień wiedzę w umiejętności

Pobierz darmową Roadmapę .NET i ułóż takie tematy jak ten w spójną ścieżkę do pierwszej pracy.

Pobieram roadmapę →