Code Review in C#: What to Check to Keep Your Code Healthy

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

Code Review in C#: Not Just a Checkbox, but a Production Saver

\n\n

Have you ever seen code that works but makes you want to close your eyes? "Magic numbers", loops within loops, async void and null where it shouldn't be. Code review in C# is not a bureaucratic procedure, but the last line of defense before a bug goes into production. Or, even worse, before your colleagues have to maintain the code, cursing the author.

\n\n

In this article, we'll break down what you should really pay attention to when reviewing C# code. No fluff — only specific cases, antipatterns, and examples. If you're a junior — this is your checklist. If you're a senior — refresh your memory. Let's go.

\n\n

1. Null — The Main Enemy of a C# Developer

\n\n

The infamous NullReferenceException is the cause of millions of sleepless nights. The first thing we check during a code review: protection against null.

\n\n

What should raise a red flag?

\n
    \n
  • Lack of a null check before accessing properties.
  • \n
  • Returning null from methods where a collection is expected.
  • \n
  • Ignoring nullable contexts (#nullable enable).
  • \n
\n\n

Bad:

\n
public string GetUserName(User user)\n{\n    return user.Name.ToUpper(); // user could be null!\n}
\n\n

Good (C# 8+):

\n
public string GetUserName(User? user)\n{\n    return user?.Name?.ToUpper() ?? "Unknown";\n}
\n\n

Code review tip: require enabling Nullable in new projects. It's not just trendy, it saves you from silly mistakes. C# code review without checking nullable is like driving without a seatbelt.

\n\n

2. Asynchrony: async/await Without Pitfalls

\n\n

Asynchronous programming in C# is a powerful tool, but when used incorrectly, it turns into a time bomb. During a review, we check for three main sins.

\n\n

Sin #1: async void

\n

async void methods cannot be tracked — an exception will fall into the final thread and kill the process. Only acceptable for event handlers (e.g., a button in WinForms).

\n\n

Bad:

\n
public async void LoadDataAsync()\n{\n    var data = await _service.GetDataAsync(); // An error will kill the process\n}
\n\n

Good:

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

Sin #2: Blocking Asynchronous Code

\n

.Result or .Wait() in an asynchronous context is a sure path to a deadlock.

\n\n

Bad:

\n
var result = _service.GetDataAsync().Result; // deadlock in UI applications
\n\n

Good:

\n
var result = await _service.GetDataAsync();
\n\n

Sin #3: Missing CancellationToken

\n

Long-running operations should be cancellable. If the method signature doesn't have a CancellationToken, ask the author: "What happens if the user closes the tab?"

\n\n

3. LINQ: Beauty or Slow Death?

\n\n

LINQ is elegant. But code review often reveals that behind the elegance lies O(n²) or multiple passes over a collection.

\n\n

Typical mistakes when reviewing C# code with LINQ:

\n
    \n
  • Multiple enumeration: .Count() > 0 + .First() — two passes. Use .Any() and .FirstOrDefault().
  • \n
  • Forgotten ToList(): lazy loading can cause a database query to execute after the DataReader context is already closed.
  • \n
  • Where + Select = redundancy: if you can use a single SelectMany, use it.
  • \n
\n\n

An example that should raise a red flag:

\n
var result = l                

Blogs

Book Recommendations