C# Code Review: 7 Things That Annoy Senior Developers

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Your Code Makes a Senior Twitch?

\n\n

You submitted a pull request. Five minutes passed. A message pops up in the chat: "How about we rewrite this block?" and a dozen comments under every other line. Sound familiar? If you write in C# and work in a team, code review is not just a checkbox in Jira. It's a moment of truth.

\n\n

I've collected typical comments that seniors leave on C# code reviews. This isn't about syntax — it's about mindset. About turning "just working code" into code that no one wants to rewrite on the first Friday.

\n\n

Let's dive into the C# antipatterns that annoy even the calmest team leads.

\n\n

1. Magic Numbers and Strings: "What Does That Mean?"

\n\n

The most common comment on a C# code review is a question about numbers. You write if (status == 3), and a senior immediately asks: "What is 3? Is it the 'Processing' status or 'Deleted'?"

\n\n

Bad:

\n
if (order.Status == 3 && days > 7)\n{\n    CancelOrder(order);\n}\n
\n\n

Good:

\n
private const int OrderStatusCancelled = 3;\nprivate const int MaxDaysBeforeAutoCancel = 7;\n\nif (order.Status == OrderStatusCancelled && days > MaxDaysBeforeAutoCancel)\n{\n    CancelOrder(order);\n}\n
\n\n

Even better — move it to an enum. Seniors love readable code where you don't have to dig into the database to understand the business logic. This is a basic code review C# rule: the code should speak for itself.

\n\n

2. Async Void — The Silent Application Killer

\n\n

If you write async void anywhere except event handlers (e.g., in WPF or WinForms), get ready for a big minus. Async void cannot be tracked — an exception will fall into the void and crash the process.

\n\n

Bad:

\n
public async void LoadData()\n{\n    var data = await _repository.GetDataAsync();\n    // If this fails — the application crashes without an error message\n}\n
\n\n

Good:

\n
public async Task LoadDataAsync()\n{\n    var data = await _repository.GetDataAsync();\n}\n
\n\n

During a C# code review, a senior will definitely point this out. Remember: async Task is your friend, async void is your enemy (except for events).

\n\n

3. Godzilla Classes: Single Responsibility Principle

\n\n

You open a file, and it has 2000 lines. One class does everything: accesses the database, sends emails, generates reports, and even makes coffee. This is a classic C# antipattern — the God Object.

\n\n

A senior on a C# code review will say: "Let's break this into several classes." And they'll be right.

\n\n

Example of a violation:

\n
public class OrderService\n{\n    public void ProcessOrder(Order order)\n    {\n        // 1. Validation\n        // 2. Save to DB\n        // 3. Send email\n        // 4. Logging\n    }\n}\n
\n\n

How it should be:

\n
public 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\n

This isn't just "pretty." It's testable. You can mock the repository and test only the processing logic. C# refactoring in this style is a must-have for any project.

\n\n

4. Exceptions as Control Flow

\n\n

Blogs

Book Recommendations