Einleitung: Warum Ihr Code beim Senior einen Tick auslöst
\n\nSie haben einen Pull-Request gesendet. Fünf Minuten vergehen. Im Chat kommt: „Können wir diesen Block hier umschreiben?“ und ein Dutzend Kommentare unter jeder zweiten Zeile. Kommt Ihnen das bekannt vor? Wenn Sie in C# schreiben und im Team arbeiten, ist Code-Review nicht nur ein Häkchen in Jira. Es ist der Moment der Wahrheit.
\n\nIch habe typische Anmerkungen gesammelt, die Seniors bei C#-Code-Reviews hinterlassen. Es geht nicht um Syntax – es geht um Denkweise. Darum, wie man aus „einfach funktionierendem Code“ Code macht, den man nicht gleich am ersten Freitag wieder umschreiben möchte.
\n\nLos geht's mit der Analyse der C#-Antipatterns, die selbst die ruhigsten Teamleiter nerven.
\n\n1. Magische Zahlen und Zeichenketten: „Was soll das bedeuten?“
\n\nDer häufigste Kommentar bei einem C#-Code-Review ist die Frage nach Zahlen. Sie schreiben if (status == 3), und der Senior fragt sofort: „Was ist 3? Ist das der Status 'In Bearbeitung' oder 'Gelöscht'?“.
Schlecht:
\nif (order.Status == 3 && days > 7)\n{\n CancelOrder(order);\n}\n\n\nGut:
\nprivate const int OrderStatusCancelled = 3;\nprivate const int MaxDaysBeforeAutoCancel = 7;\n\nif (order.Status == OrderStatusCancelled && days > MaxDaysBeforeAutoCancel)\n{\n CancelOrder(order);\n}\n\n\nNoch besser ist es, dies in ein Enum auszulagern. Seniors lieben lesbaren Code, bei dem man nicht in die Datenbank schauen muss, um die Geschäftslogik zu verstehen. Das ist eine grundlegende Code-Review-Regel für C#: Der Code sollte für sich selbst sprechen.
\n\n2. Async void – der stille Killer von Anwendungen
\n\nWenn Sie async void irgendwo anders als in Event-Handlern (z. B. in WPF oder WinForms) schreiben, machen Sie sich auf eine dicke Minusnote gefasst. Async void kann nicht verfolgt werden – eine Ausnahme fällt ins Nichts und legt den Prozess lahm.
Schlecht:
\npublic async void LoadData()\n{\n var data = await _repository.GetDataAsync();\n // Wenn hier ein Fehler auftritt, stürzt die Anwendung ohne Fehlermeldung ab\n}\n\n\nGut:
\npublic async Task LoadDataAsync()\n{\n var data = await _repository.GetDataAsync();\n}\n\n\nBei einem C#-Code-Review wird der Senior Sie garantiert darauf hinweisen. Merken Sie sich: async Task ist Ihr Freund, async void ist Ihr Feind (außer bei Events).
3. Godzilla-Klassen: Single Responsibility Principle
\n\nSie öffnen eine Datei und sie hat 2000 Zeilen. Eine Klasse macht alles: greift auf die Datenbank zu, sendet E-Mails, generiert Berichte und brüht noch Kaffee auf. Das ist ein klassisches C#-Antipattern – das God Object.
\n\nEin Senior wird beim C#-Code-Review sagen: „Lass uns das in mehrere Klassen aufteilen.“ Und er wird recht haben.
\n\nBeispiel für einen Verstoß:
\npublic class OrderService\n{\n public void ProcessOrder(Order order)\n {\n // 1. Validierung\n // 2. Speichern in der DB\n // 3. E-Mail versenden\n // 4. Logging\n }\n}\n\n\nSo sollte es sein:
\npublic class OrderProcessor\n{\n private readonly IOrderValidator _validator;\n private readonly IOrderRepository _repository;\n private readonly INotificationService _notificationService;\n\n public OrderProcessor(\n IOrderValidator validator,\n IOrderRepository repository,\n INotificationService notificationService)\n {\n _validator = validator;\n _repository = repository;\n _notificationService = notificationService;\n }\n\n public async Task ProcessOrderAsync(Order order)\n {\n _validator.Validate(order);\n await _repository.SaveAsync(order);\n await _notificationService.SendConfirmationAsync(order);\n }\n}\n\n\nDas ist nicht nur „hübsch“. Es ist testbar. Sie können das Repository mocken und nur die Verarbeitungslogik prüfen. C#-Refactoring in diesem Stil ist ein Must-have für jedes Projekt.
\n\n4. Ausnahmen als Kontrollstrukturen
\n\n