Code review в C#: что проверять и как давать обратную связь новичкам

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Code review в C#: с чего начать и что искать

Code review (рецензирование кода) — это не просто формальность, а мощный инструмент повышения качества проекта и роста команды. Для начинающих разработчиков на C# процесс проверки чужого кода часто вызывает страх: «А вдруг я пропущу баг?», «Как сказать коллеге, что его код плохой?». В этой статье мы разберем, на что обращать внимание при code review в .NET-проектах и как давать обратную связь так, чтобы вас услышали, а не обиделись.

Мы не будем говорить об очевидных вещах вроде синтаксических ошибок — их отлавливает компилятор. Наша цель — научиться видеть проблемы архитектуры, читаемости и производительности, а также правильно формулировать замечания.

1. Архитектура и принципы SOLID в C#

Первое, что нужно проверить в коде на C# — соответствует ли он принципам SOLID. Даже в небольшом методе можно увидеть нарушение единственной ответственности (Single Responsibility).

Что проверять:

  • Размер методов и классов. Если метод длиннее 20-30 строк — скорее всего, он делает слишком много. Предложите разбить его на несколько приватных методов.
  • Инверсия зависимостей. Классы не должны создавать свои зависимости через new. Вместо этого используйте внедрение зависимостей (DI). Пример плохого кода:
// Плохо: класс сам создает зависимость
public class OrderService
{
    private readonly EmailSender _sender = new EmailSender();

    public void ProcessOrder(Order order)
    {
        // логика...
        _sender.SendEmail(order.CustomerEmail);
    }
}

Правильный вариант — через интерфейс и DI:

// Хорошо: зависимость внедряется
public class OrderService
{
    private readonly IEmailSender _sender;

    public OrderService(IEmailSender sender)
    {
        _sender = sender;
    }

    public void ProcessOrder(Order order)
    {
        // логика...
        _sender.SendEmail(order.CustomerEmail);
    }
}
  • Принцип подстановки Барбары Лисков (LSP). Наследники не должны ломать поведение базового класса. Например, если у вас есть класс Bird с методом Fly(), а вы создаете Penguin : Bird — это нарушение LSP, так как пингвины не летают. Лучше выделить интерфейс IFlyable.

2. Обработка ошибок и исключения в .NET

В C# есть мощная система исключений, но новички часто используют её неправильно. При code review обращайте внимание на следующие моменты:

  • Пустые блоки catch. Код вида catch (Exception) { } — это бомба замедленного действия. Ошибка проглатывается, и вы никогда не узнаете о проблеме. Всегда логируйте исключение или пробрасывайте его дальше.
  • Слишком общие исключения. Ловить Exception — плохая практика. Старайтесь ловить конкретные типы: SqlException, InvalidOperationException и т.д.
  • Использование исключений для управления потоком. Не используйте try-catch вместо if-else. Пример плохого кода:
// Плохо: исключение как часть логики
try
{
    int.Parse(userInput);
}
catch (FormatException)
{
    Console.WriteLine("Неверный формат");
}

Правильный вариант — int.TryParse():

// Хорошо: проверка без исключения
if (int.TryParse(userInput, out int result))
{
    // работаем с result
}
else
{
    Console.WriteLine("Неверный формат");
}

3. Производительность и работа с памятью

Для начинающих разработчиков на C# тема производительности часто остается за кадром. Однако code review — отличный момент указать на неэффективные конструкции.

Типичные проблемы:

  • Избыточные LINQ-запросы. Например, вызов .ToList() после каждого шага приводит к множественному копированию коллекции. Лучше выполнить один раз в конце цепочки.
  • Работа со строками. Конкатенация строк в цикле через + — это убийство памяти. Используйте StringBuilder.
  • Асинхронность. Если метод вызывает .Result или .Wait() — это может привести к deadlock. Проверяйте, что async методы используют await последовательно.

Пример неоптимального кода:

// Плохо: множественная конкатенация
string result = "";
for (int i = 0; i < 1000; i++)
{
    result += i.ToString();
}

Исправленный вариант:

// Хорошо: StringBuilder
var sb = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
    sb.Append(i);
}
string result = sb.ToString();

4. Как давать обратную связь: психология code review

Самая сложная часть code review — это не найти баг, а правильно донести замечание. Новички часто воспринимают критику кода как критику личности. Чтобы этого избежать, следуйте простым правилам:

Правила конструктивного фидбека: