Code review in C#: what to check and how to give feedback
Code review is not just a formality, but one of the key processes that ensures code quality. This is especially important for projects in C# and .NET, where high performance, readability, and compliance with modern standards play a crucial role. In this article, we will break down what to look for when reviewing C# code and how to give feedback that is useful and constructive.
1. Architecture and compliance with SOLID principles
Before looking at specific lines of code, evaluate the overall architecture. In C#, this is especially important due to the widespread use of OOP.
- Single Responsibility: each class and method should solve one task. If a method does too much — that's a reason for review.
- Open/Closed: check whether functionality can be extended without modifying existing code (for example, through interfaces or abstract classes).
- Dependency Injection: in .NET Core/5+ DI is the standard. Make sure dependencies are passed through the constructor, not created inside the class.
// Bad: violation of SRP and DIpublic class OrderService{ private readonly SqlConnection _connection = new SqlConnection("..."); public void ProcessOrder(Order order) { // Validation logic // Database saving logic // Email sending logic }}
// Good: separation into services and DIpublic class OrderService{ private readonly IOrderRepository _orderRepository; private readonly IEmailService _emailService;
public OrderService(IOrderRepository orderRepository, IEmailService emailService) { _orderRepository = orderRepository; _emailService = emailService; }
public void ProcessOrder(Order order) { _orderRepository.Save(order); _emailService.SendConfirmation(order); }}2. Security and error handling
Security is a critical part of any application in C#. Pay attention to the following aspects:
- SQL injections: use parameterized queries or Entity Framework, not string concatenation.
- Exceptions: do not swallow exceptions with empty
catchblocks. Log errors and usefinallyfor resource cleanup. - Null safety: in C# 8+ use nullable reference types. Check method arguments for
null.
// Bad: vulnerable to SQL injectionsvar query = "SELECT * FROM Users WHERE Name = '" + userName + "'";
// Good: parameterized queryvar command = new SqlCommand("SELECT * FROM Users WHERE Name = @name", connection);command.Parameters.AddWithValue("@name", userName);Also check that the application correctly handles exceptions at system boundaries (for example, in ASP.NET Core controllers).
3. Performance and memory management
C# is a language with automatic memory management, but that doesn't mean you can forget about performance. During review, pay attention to:
- LINQ queries: avoid multiple iterations over collections. For example,
.ToList()after every.Where()can significantly slow down performance. - Asynchrony: use
async/awaitfor I/O operations, but do not overuse.Resultor.Wait()— this can cause deadlocks. - Object pool: for heavy objects (for example, database connections), use pooling instead of creating them each time.
// Bad: multiple iterationsvar filtered = items.Where(x => x.IsActive).ToList();var sorted = filtered.OrderBy(x => x.Name).ToList