Einleitung: Warum Fehler normal sind
Der Weg jedes Entwicklers beginnt mit Fehlern. C# (.NET) ist eine mächtige und streng typisierte Sprache, die weniger vergibt als dynamische Sprachen, aber dafür Zuverlässigkeit und Leistung bietet. In diesem Artikel analysieren wir die 4 häufigsten Fallstricke, auf die Anfänger treten, und zeigen, wie man sie umgeht. Der Artikel ist sowohl für diejenigen nützlich, die gerade erst mit C# beginnen, als auch für diejenigen, die ihr Wissen auffrischen möchten.
1. Ignorieren von null und NullReferenceException
Der häufigste Fehler in C# ist NullReferenceException. Er tritt auf, wenn Sie versuchen, auf ein Member eines Objekts zuzugreifen, das gleich null ist.
Beispiel des Problems
string text = null;int length = text.Length; // Fehler! NullReferenceExceptionAnfänger vergessen oft, von Methoden zurückgegebene Werte zu überprüfen, oder verlassen sich darauf, dass das Objekt definitiv existiert.
Wie man es richtig macht
- Überprüfen Sie Objekte immer auf
null, bevor Sie sie verwenden. - Verwenden Sie die Operatoren
?.(null-conditional) und??(null-coalescing).
string text = GetText(); // kann null zurückgebenint? length = text?.Length; // wenn text == null, ist length nullint safeLength = text?.Length ?? 0; // wenn null, dann 0Console.WriteLine(safeLength);Außerdem gibt es seit C# 8.0+ nullable reference types, die über #nullable enable aktiviert werden. Sie zwingen Sie, explizit anzugeben, ob eine Variable null sein kann, und warnen bereits zur Kompilierzeit vor potenziellen Problemen.
2. Falsche Verwendung von var und Verlust der Lesbarkeit
Das Schlüsselwort var erlaubt es dem Compiler, den Typ der Variable selbst zu bestimmen. Das ist praktisch, aber Anfänger missbrauchen es oft, was den Code unleserlich macht.
Beispiel für schlechten Code
var data = GetData();var result = Process(data);var output = Transform(result); // Was für Typen? Unklar.Nach einem Monat können Sie (oder Ihr Kollege) nicht schnell verstehen, welchen Typ data hat, ohne in die Methodendefinition zu schauen.
Wann man var verwenden sollte
- Wenn der Typ aus der rechten Seite offensichtlich ist (z.B.
var list = new List<int>();) - Bei der Arbeit mit anonymen Typen und LINQ-Abfragen.
// Gut: Typ ist offensichtlichvar numbers = new List<int> { 1, 2, 3 };
// Gut: anonymer Typvar person = new { Name = "John", Age = 30 };
// Schlecht: Typ ist unklarvar config = LoadConfiguration(); // Besser: Configuration config = LoadConfiguration();Goldene Regel: Verwenden Sie var nur dann, wenn es die Lesbarkeit erhöht und nicht verringert.
3. Verschlingen von Ausnahmen und leere catch-Blöcke
Viele Anfänger schreiben bei Ausnahmen einen leeren catch oder geben nur eine Meldung aus, ohne den Fehler zu analysieren. Das macht das Programm instabil und erschwert das Debugging.
Beispiel für ein Anti-Pattern
try{ int.Parse("keine Zahl");}catch (Exception){ // Wir tun nichts — der Fehler wird "verschluckt"}Die Anwendung läuft weiter, aber in einem ungültigen Zustand. Der Benutzer erfährt nichts vom Problem, und Daten könnten beschädigt werden.
Wie man Ausnahmen richtig behandelt
- Fangen Sie keine allgemeinen
Exception, wenn Sie nicht vorhaben, alle Fehlertypen zu behandeln. - Fangen Sie nur die Ausnahmen, die Sie behandeln können (z.B.
FormatException,FileNotFoundException). - Verwenden Sie
finallyzum Freigeben von Ressourcen (Dateien, Verbindungen). - Protokollieren Sie Fehler.
try{ int number = int.Parse(userInput);}catch (FormatException ex){ // Protokollieren und dem Benutzer mitteilen Console.WriteLine("Ungültiges Format. Bitte geben Sie eine Zahl ein."); // Log.Error(ex);}4. Falsches Verständnis von Wert- und Referenztypen
In C# gibt es Werttypen (struct, int, bool) und Referenztypen (class, string, array). Anfänger verwechseln oft ihr Verhalten bei der Zuweisung und Übergabe an Methoden.
Beispiel des Problems
struct Point { public int X; public int Y; }
void ModifyPoint(Point p){ p.X = 10; // Ändert nur die Kopie}
Point point = new Point { X = 1, Y = 2 };ModifyPoint(point);Console.WriteLine(point.X); // Gibt 1 aus, nicht 10!Anfänger erwarten, dass point nach dem Aufruf von ModifyPoint geändert wird, aber struct wird als Wert übergeben — eine Kopie wird erstellt.
Wie man es richtig macht
- Verwenden Sie
classanstelle vonstruct, wenn Sie änderbare Objekte benötigen. - Übergeben Sie Parameter explizit mit
refoderout, wenn Sie Werttypen ändern müssen.
// Option 1: Klasse verwendenclass PointClass { public int X; public int Y; }
void ModifyPoint(PointClass p){ p.X = 10; // Ändert das Originalobjekt}
// Option 2: ref verwendenvoid ModifyPointRef(ref Point p){ p.X = 10;}
Point point = new Point { X = 1, Y = 2 };ModifyPointRef(ref point);Console.WriteLine(point.X); // Gibt 10 ausWichtig: string ist ein Referenztyp, verhält sich aber wie ein Werttyp aufgrund seiner Unveränderlichkeit (Immutable). Jede Änderung erstellt eine neue Zeichenfolge.
Fazit
Fehler sind ein unvermeidlicher Teil des Lernens. Die Hauptsache ist, sie zu analysieren und zu verstehen, warum sie aufgetreten sind. Die besprochenen Fallstricke sind nur die Spitze des Eisbergs, aber wenn Sie sie vermeiden, wird Ihr Code zuverlässiger und lesbarer.
Denken Sie daran: Ein guter Entwickler ist nicht der, der keine Fehler macht, sondern der, der weiß, wie man sie findet und behebt. Üben Sie, schreiben Sie Code, lesen Sie die Dokumentation und haben Sie keine Angst, Fehler zu machen. Viel Erfolg beim Programmieren!