Code review в C#: что проверять и как давать обратную связь
Code review — один из самых мощных инструментов повышения качества кода. Для начинающих C# разработчиков это часто кажется стрессом: страшно, что ваш код раскритикуют, или непонятно, что именно нужно искать в чужом коде. На самом деле, хороший code review — это диалог, а не экзамен. В этой статье мы разберем, на что обращать внимание при проверке C# кода (особенно в экосистеме .NET) и как формулировать замечания так, чтобы они помогали, а не обижали.
1. Что проверять в C# коде: чек-лист для ревьювера
Когда вы открываете pull request (PR) коллеги, глаза разбегаются. Чтобы не утонуть в деталях, используйте системный подход. Вот ключевые зоны, которые нужно проверить в любом C# проекте.
1.1. Архитектура и читаемость
Сначала оцените общую картину. Ответьте на вопросы:
- Решает ли этот код поставленную задачу?
- Не дублирует ли он существующую логику (принцип DRY)?
- Понятны ли названия классов, методов и переменных?
Плохо:
public void DoStuff(int a, int b)
{
var x = a + b;
// ... еще 50 строк
}
Хорошо:
public int CalculateTotalPrice(int basePrice, int taxAmount)
{
return basePrice + taxAmount;
}
Имя метода и параметров сразу говорят о назначении. Это снижает когнитивную нагрузку на читателя.
1.2. Обработка ошибок и null-безопасность
C# — язык с развитой системой типов, но NullReferenceException — частая проблема. Проверяйте:
- Используется ли
nullпроверки (?.,??,??=)? - Есть ли обработка исключений (try-catch) там, где это необходимо?
- Не проглочены ли исключения в пустом catch?
Пример опасного кода:
var user = GetUserById(id);
Console.WriteLine(user.Name); // Ошибка, если user == null
Безопасный вариант:
var user = GetUserById(id);
Console.WriteLine(user?.Name ?? "Гость");
1.3. Производительность и LINQ
LINQ удобен, но может быть неэффективным. Проверяйте:
- Не делается ли множественный проход по коллекции (например,
.Where().Select().ToList()на IQueryable)? - Используется ли
Any()вместоCount() > 0для проверки наличия элементов? - Нет ли лишних материализаций (
.ToList(),.ToArray()) в середине цепочки?
Плохо:
var list = items.Where(x => x.IsActive).ToList();
var first = list.FirstOrDefault();
Лучше:
var first = items.FirstOrDefault(x => x.IsActive);
1.4. Асинхронность и Task
В .NET асинхронность — стандарт. Смотрите:
- Не забыт ли
awaitперед асинхронным вызовом? - Нет ли блокирующих вызовов (
.Result,.Wait()) в синхронном контексте? - Соблюдается ли convention: асинхронные методы заканчиваются на
Async?
Антипаттерн:
var data = GetDataAsync().Result; // Может вызвать deadlock
Правильно:
var data = await GetDataAsync();
2. Как давать обратную связь: мягко, но конструктивно
Даже идеальный чек-лист бесполезен, если ваши комментарии звучат как критика. Вот несколько правил, которые помогут сделать code review полезным для всех.
2.1. Используйте "Я-сообщения" и вопросы
Вместо "Ты написал плохой код" скажите "Мне кажется, этот метод можно упростить. Что думаешь?".
Примеры формулировок:
- "Я не уверен, что понимаю логику здесь. Не могли бы вы добавить комментарий?"
- "Вижу, что ты используешь
varдля всех переменных. В этом случае типIEnumerableнеочевиден. Может, объявим явно?" - "Отличное решение с использованием паттерна Strategy! Есть мысль, как это протестировать?"
2.2. Разделяйте важные и неважные замечания
Не все ошибки одинаково вредны. Критические (ошибки логики, утечки памяти) требуют обязательного исправления. Стилистические (отступы, пробелы) можно оставить на усмотрение автора или автоматизировать через StyleCop/EditorConfig.
Используйте теги в комментариях: [Must Fix], [Suggestion], [Nitpick].
2.3. Хвалите за хорошие решения
Code review — это не только поиск ошибок. Если вы видите элегантный код или удачное использование фичи C# — напишите об этом. Это мотивирует и показывает, что вы внимательно читаете код.
Пример: "Круто, что ты использовал record для DTO — это сделало код намного чище!"
3. Типичные ошибки новичков в C# при code review
Зная, где чаще всего спотыкаются джуниоры, вы сможете быстрее находить проблемы. Вот топ-5 ошибок.
- Избыточная сложность: Попытка использовать LINQ там, где простой цикл
forбыл бы понятнее. - Игнорирование using: Забывают освобождать ресурсы (
SqlConnection,StreamReader). - Магические числа: Исп