Debugging-Techniken in C#
Lernen Sie Debugging-Techniken in C# mit Breakpoints und Analyse-Tools zur schnellen Fehlerbehebung.
Im Softwareentwicklungsprozess ist Debugging (Fehlerbehebung) ein systematischer Vorgang, bei dem das unerwartete Verhalten eines Programms analysiert und fehlerhafter Code identifiziert wird. In C# bieten Tools wie Visual Studio und Visual Studio Code leistungsstarke Debugging-Funktionen, die es Entwicklern ermöglichen, den Programmablauf Schritt für Schritt zu verfolgen, Variablenwerte zu prüfen und den Programmfluss zu analysieren.
Unterschied zwischen Debug- und Release-Modus
.NET-Projekte verfügen über zwei Haupt-Build-Konfigurationen:
- Debug: Wird während der Entwicklung verwendet. Enthält Symbole und zusätzliche Informationen, die das Debuggen erleichtern.
- Release: Wird für die Produktionsversion verwendet. Optimierungen werden vorgenommen, Debugging-Informationen entfernt.
// In Visual Studio über das obere Menü auswählbar:
// [Debug ▼] → [Release]
Im Debug-Modus kann das Programm Zeile für Zeile ausgeführt werden, was volle Kontrolle über den Codefluss ermöglicht.
Haltepunkte (Breakpoints)
Ein Breakpoint ist ein Marker, der das Programm an einer bestimmten Zeile anhält. Dadurch läuft das Programm bis zu dieser Zeile und pausiert, sodass alle aktuellen Variablenwerte überprüft werden können.
class Program
{
static void Main()
{
int a = 5;
int b = 0;
int c = a / b; // Fehler: DivideByZeroException
Console.WriteLine(c);
}
}
Im obigen Beispiel kann ein Breakpoint an der Zeile int c = a / b; gesetzt werden,
um das Programm dort anzuhalten und die Werte von a und b im Fenster „Locals“ zu überprüfen.
Schrittweise Ausführung (Stepping)
In Visual Studio können folgende Tastenkombinationen zum schrittweisen Ausführen des Codes verwendet werden:
- F10 – Step Over: Führt die aktuelle Zeile aus, ohne in aufgerufene Methoden einzutreten.
- F11 – Step Into: Tritt in die aufgerufene Methode der aktuellen Zeile ein.
- Shift + F11 – Step Out: Verlässt die aktuelle Methode.
- F5 – Continue: Führt das Programm bis zum nächsten Breakpoint aus.
Mit diesen Werkzeugen lässt sich der Programmfluss genau steuern und die Ursache eines Fehlers präzise lokalisieren.
Variablenüberwachung (Watch- & Autos-Fenster)
Visual Studio bietet die Möglichkeit, Variablenwerte während des Debuggens in Echtzeit zu überwachen:
- Watch Window: Überwacht manuell hinzugefügte Variablen.
- Locals Window: Listet automatisch alle Variablen im aktuellen Gültigkeitsbereich auf.
- Autos Window: Zeigt Variablen an, die mit den zuletzt ausgeführten Zeilen in Zusammenhang stehen.
Wenn Sie den Mauszeiger über eine Variable bewegen, wird ihr aktueller Wert in einem Tooltip angezeigt.
Verwendung von Immediate und Watch
Das Immediate Window ermöglicht es, während des Debuggens Code auszuführen. Sie können Variablenwerte ändern oder kurze Ausdrücke testen, ohne das Programm neu zu starten.
// Beispiel für Immediate Window:
// ? a + b
// ? myList.Count
// a = 25
So können Sie Berechnungen testen oder Variablenwerte anpassen, ohne die Anwendung zu beenden.
Bedingte Haltepunkte (Conditional Breakpoints)
Manchmal soll das Programm nicht bei jeder Iteration anhalten, sondern nur bei bestimmten Bedingungen. Dafür können Sie einen bedingten Breakpoint verwenden.
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
}
Wenn Sie in dieser Schleife einen Breakpoint setzen und im Menü „Conditions“ die Bedingung
i == 50 eingeben, hält das Programm nur beim 50. Durchlauf an.
Exception Settings (Fehlerbehandlungseinstellungen)
Unter Debug → Windows → Exception Settings können Sie festlegen,
bei welchen Fehlertypen das Programm anhalten soll.
Zum Beispiel können Sie einstellen, dass nur bei NullReferenceException
oder InvalidOperationException gestoppt wird.
Diese Funktion verhindert unnötige Unterbrechungen in komplexen Anwendungen.
Debugging innerhalb von Try / Catch-Blöcken
Selbst wenn Fehler innerhalb eines try / catch-Blocks abgefangen werden,
kann Visual Studio – sofern „Break on User-Unhandled Exceptions“ aktiviert ist –
an der Zeile anhalten, in der die Ausnahme auftritt.
try
{
int[] array = new int[3];
array[5] = 10; // IndexOutOfRangeException
}
catch (Exception ex)
{
Console.WriteLine("Fehler abgefangen: " + ex.Message);
}
So können Sie den Zustand der Anwendung unmittelbar vor dem Auftreten der Ausnahme untersuchen.
Verwendung von Debug.WriteLine()
Die Methode Debug.WriteLine() schreibt Informationsmeldungen während des Debuggens in das Ausgabefenster (Output Window).
Dies ist nützlich, um Protokolle im Hintergrund zu führen, ohne die Konsolenausgabe zu verändern.
using System.Diagnostics;
class Program
{
static void Main()
{
for (int i = 0; i < 3; i++)
{
Debug.WriteLine($"Schritt {i} abgeschlossen.");
}
Console.WriteLine("Programm beendet.");
}
}
Diese Meldungen sind nur im Debug-Modus sichtbar und werden in der Release-Version nicht ausgeführt.
Logging und Fehlerüberwachung
Debugging dient nicht nur der sofortigen Analyse, sondern auch der langfristigen Überwachung einer Anwendung.
Dafür können Logging-Bibliotheken wie Serilog, NLog oder Microsoft.Extensions.Logging verwendet werden.
using Microsoft.Extensions.Logging;
class Program
{
static void Main()
{
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
});
var logger = loggerFactory.CreateLogger<Program>();
try
{
int a = 10, b = 0;
int c = a / b;
}
catch (Exception ex)
{
logger.LogError(ex, "Ein Fehler ist aufgetreten!");
}
}
}
Logging ermöglicht die Nachverfolgung von Fehlern nicht nur während der Entwicklung, sondern auch in produktiven Systemen.
Beispiel: Debugging eines Benutzer-Logins
Das Programm hält an der Stelle an, an der der Breakpoint gesetzt wurde.
Im folgenden Beispiel wird ein Fehler in einem Benutzeranmeldeformular Schritt für Schritt mit dem Debugger untersucht.
class LoginService
{
public bool Login(string username, string password)
{
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
throw new ArgumentException("Benutzername oder Passwort darf nicht leer sein.");
return username == "admin" && password == "1234";
}
}
class Program
{
static void Main()
{
var service = new LoginService();
Console.Write("Benutzername: ");
string? u = Console.ReadLine();
Console.Write("Passwort: ");
string? p = Console.ReadLine();
try
{
bool result = service.Login(u, p);
Console.WriteLine(result ? "Login erfolgreich" : "Ungültige Anmeldedaten");
}
catch (Exception ex)
{
Console.WriteLine($"Fehler: {ex.Message}");
}
}
}
Du kannst einen Breakpoint auf jede beliebige Zeile setzen und Variablen Schritt für Schritt untersuchen.
Wenn du einen Breakpoint auf die return-Zeile setzt, kannst du die Werte von username und password in Echtzeit überprüfen
und analysieren, warum die Bedingung false zurückgibt.
Best Practices
- Fange nicht jeden Fehler mit
try / catchab – fange sie in spezifischen Schichten (z. B. UI oder Service-Schicht). - Verwende
Debug.WriteLineoder ein Logging-Framework anstelle vonConsole.WriteLine. - Nutze „Step Over“ statt „Step Into“, um unnötige Details zu vermeiden.
- Fokussiere dich mit bedingten Breakpoints auf spezifische Szenarien.
- Teste Fehler mit Exception Simulation-Techniken (z. B. ungültige Eingaben, null-Werte).
TL;DR
- Debugging: Der Prozess, den Programmablauf Schritt für Schritt zu verfolgen, um Fehler zu finden.
- Breakpoint: Hält die Ausführung an einer bestimmten Codezeile an.
- Watch & Immediate: Werkzeuge zur Überwachung von Variablen und zum sofortigen Ausführen von Code.
- Debug.WriteLine: Entwicklerbezogene Protokollausgabe (nur im Debug-Modus).
- Logging: Zeichnet Fehler und Ereignisse auf, auch in Produktionsumgebungen.
- Bedingte Breakpoints: Stoppen nur unter bestimmten Bedingungen und verbessern die Effizienz.
Ähnliche Artikel
Ausnahmebehandlung in C# (try, catch, finally)
Erlernen Sie die Ausnahmebehandlung in C# mit try-, catch- und finally-Blöcken zur sicheren Fehlerverwaltung anhand von Beispielen.
Reflection und Late Binding in C#
Lernen Sie Reflection und Late Binding in C#, um Typen zur Laufzeit zu analysieren und dynamische Systeme zu erstellen.
Visual Studio / VS Code Tipps für C#
Lernen Sie Visual Studio und VS Code Tipps für C#, um produktiver mit Shortcuts und Tools zu arbeiten.