Code review em C#: o que verificar e como dar feedback na prática
\n\nCode review não é apenas um procedimento formal antes do merge de um pull request. É uma ferramenta poderosa para melhorar a qualidade do código, disseminar conhecimento na equipe e prevenir bugs. Isso é especialmente relevante para C# e o ecossistema .NET, onde existem muitas nuances: desde gerenciamento de memória e assincronicidade até tipagem forte e LINQ.
\n\nNeste artigo, vamos analisar exatamente o que observar ao revisar código C# e como dar feedback de forma que você seja ouvido, não odiado.
\n\n1. Arquitetura e lógica: "Por que estamos fazendo isso?"
\n\nAntes de olhar para formatação e nomes de variáveis, certifique-se de que a tarefa sendo resolvida faz sentido. Esta é a etapa mais importante, mas frequentemente ignorada.
\n\n- \n
- Conformidade com requisitos: O código resolve exatamente o problema de negócio descrito no ticket? Não há funcionalidade desnecessária (YAGNI)? \n
- Violação dos princípios SOLID: A classe se transformou em um "objeto divino"? Há uma clara separação de responsabilidades? Por exemplo, a lógica de negócios está misturada com a lógica de acesso a dados? \n
- Complexidade excessiva: É possível resolver o problema de forma mais simples? Às vezes, os desenvolvedores escrevem padrões complexos onde um simples
if-elseou um loop simples seria suficiente. \n
// ❌ Ruim: A classe faz demais\npublic class UserService\n{\n public void RegisterUser(string email, string password)\n {\n // Validação\n if (!email.Contains("@"))\n throw new Exception("Invalid email");\n\n // Hash da senha\n var hash = BCrypt.HashPassword(password);\n\n // Salvando no banco\n using var db = new AppDbContext();\n db.Users.Add(new User { Email = email, PasswordHash = hash });\n db.SaveChanges();\n\n // Enviando email\n SmtpClient.Send("welcome@site.com", email, "Welcome!");\n }\n}\n\n// ✅ Bom: Separação em camadas (SRP)\npublic class UserRegistrationService\n{\n private readonly IUserRepository _repository;\n private readonly IEmailService _emailService;\n\n public UserRegistrationService(IUserRepository repository, IEmailService emailService)\n {\n _repository = repository;\n _emailService = emailService;\n }\n\n public async Task<Result> RegisterAsync(string email, string password)\n {\n if (!EmailValidator.IsValid(email))\n return Result.Failure("Invalid email");\n\n var user = User.Create(email, password);\n await _repository.AddAsync(user);\n await _emailService.SendWelcomeAsync(email);\n\n return Result.Success();\n }\n}\n\n2. Desempenho e segurança: "Isso vai derrubar o servidor?"
\n\n.NET é um framework poderoso, mas é fácil usá-lo incorretamente. Aqui está o que vale a pena verificar em cada revisão.
\n\n- \n
- Assincronicidade (async/await): Existem chamadas bloqueantes (
.Result,.Wait()) em código assíncrono? Isso prejudica o desempenho. UseConfigureAwait(false)em bibliotecas. \n - Vazamentos de memória: Esqueceram de liberar recursos
IDisposable? Ousingestá sendo usado paraStream,SqlConnection, etc.? \n - Injeção de SQL: As consultas estão sendo construídas por concatenação de strings? No C# moderno com Entity Framework ou Dapper isso é raro, mas a verificação é obrigatória. \n
- LINQ e coleções: Existem múltiplas iterações na mesma coleção?
Any()está sendo usado em vez deCount() > 0para verificar a existência de elementos? \n
// ❌ Ruim: Chamada bloqueante e iteração múltipla\nvar task = GetDataAsync();\nvar data = task.Result; // Bloqueio de thread!\n\nif (data.Count() > 0) // Primeira it