»

»

Code Review C#: Boas Práticas + Checklist
Índice:

Code Review C#: Boas Práticas + Checklist

Índice:

Vamos ser sinceros: a maioria de nós tem uma relação de amor e ódio com code reviews. Em um dia bom, são uma colaboração genial que pega bugs e compartilha conhecimento. Em um dia ruim, parecem um gargalo burocrático onde opiniões pessoais e picuinhas de estilo travam todo o progresso.

A diferença não é mágica. É uma questão de ter um sistema. Um bom code review c# não é só sobre achar erros, é um multiplicador de força para a qualidade, consistência e velocidade do seu time. É a atividade de maior impacto que você pode fazer para melhorar sua codebase, exceto por uma reescrita completa (e ninguém quer isso).

Então, como ter mais dias bons?

kody

 

Começa concordando sobre o que estamos procurando e como falamos sobre isso.

O Contrato Social de um Bom PR

Antes mesmo de entrar no código, vamos falar do fator humano. Um pull request é uma conversa, e toda boa conversa tem algumas regras básicas. Sem elas, vira caos.

Para o Autor: Facilite a Vida do seu Revisor

Você não pediria para alguém revisar um livro sem contar a história. Não jogue um PR de 50 arquivos para o seu time com o título “bug fixes” e espere uma revisão de alta qualidade.

Escreva uma boa descrição para o PR.

Qual é o “porquê” por trás da mudança? Que problema você está resolvendo? Link para o ticket. Inclua screenshots de mudanças na UI. Se você tomou uma decisão de arquitetura específica, explique seu raciocínio. Dê ao revisor o contexto necessário para entender suas escolhas.

Revise seu próprio código primeiro.

Sério. Leia suas próprias mudanças, arquivo por arquivo. Você vai se surpreender com a quantidade de erros de digitação, console.logs esquecidos e erros lógicos simples que você mesmo pega. Isso demonstra respeito pelo tempo de quem está revisando.

Mantenha o PR pequeno.

O maior inimigo de uma boa revisão é um PR gigante. É impossível revisar 2.000 linhas de código direito. O revisor fica cansado, passa o olho por cima e só carimba um “LGTM”. Busque fazer mudanças atômicas que resolvam um único problema.

Para o Revisor: Seja um Mentor, Não um Policial

Seu trabalho não é punir o autor pelos erros. É ajudá-lo e ao time a entregar um código melhor. Sua mentalidade é tudo.

– Faça perguntas, não exigências

Em vez de “Mude isso para um dictionary”, tente “Fiquei curioso sobre o uso de uma list aqui. Um dictionary nos daria buscas mais rápidas se essa coleção crescer?”. Isso abre um diálogo em vez de encerrá-lo.

– Revise o código, não o programador

Mantenha o feedback focado na implementação técnica. “Este método está ficando um pouco longo” é um ótimo feedback. “Por que você sempre escreve métodos longos?” não é.

– Ofereça soluções, ou pelo menos aponte a direção certa

Se encontrar um problema, sugira uma forma melhor. “Isso pode levar a uma query N+1” é bom. “Isso pode levar a uma query N+1; talvez possamos usar Include() aqui para carregar os dados relacionados com eager-load?” é ainda melhor.

– Automatize as coisas pequenas

Não perca tempo e boa vontade com picuinhas de estilo, como posicionamento de chaves ou espaçamento. Isso é trabalho para uma máquina. Use um formatador de código e um linter. Falaremos mais sobre isso adiante.

O que realmente avaliar em um PR

Ok, o PR é pequeno e o contexto está claro. Estamos todos sendo legais uns com os outros. E agora? Quando você está olhando para o diff, onde deve focar sua atenção? Eu divido isso em algumas áreas principais.

Clareza e Manutenibilidade

Esta é a base. Se você não consegue entender o código, não pode verificar se ele está correto ou se tem boa performance. O “Você do Futuro” vai te agradecer por ser rigoroso aqui.

A intenção está clara? – Você consegue entender o que um método faz apenas pelo nome e assinatura? Os nomes das variáveis são descritivos (customer vs. c)? O C# nos dá tantas ferramentas de expressão, records, pattern matching, LINQ, estamos usando-as para tornar o código mais simples?

É consistente? –  O código segue os padrões e convenções estabelecidos no projeto? Consistência é uma feature. Torna o codebase previsível e mais fácil de navegar.

Os comentários explicam o porquê, e não o quê? – Um comentário como // Incrementa i é inútil. Um comentário como // Temos que iterar de trás para frente aqui porque estamos removendo itens da coleção é ouro.

Arquitetura e Design

Aqui saímos do “linha a linha” e olhamos para o todo. Essas mudanças nos preparam para o sucesso futuro ou nos deixam encurralados?

É testável? – Isso é o canário na mina de carvão para um bom design. Se o código é difícil de testar, provavelmente está muito acoplado. Estamos usando injeção de dependência para fornecer as dependências em vez de dar new nelas dentro da classe? Conseguimos mockar os serviços externos com os quais este código conversa?

Segue os princípios SOLID (com bom senso)? – Uma classe não deveria ter dez responsabilidades diferentes (Single Responsibility). Você deveria poder estender o comportamento sem modificar o código existente (Open/Closed). Não precisamos ser dogmáticos, mas esses princípios são guias fantásticos para construir software flexível.

Estamos introduzindo novas dependências com sabedoria? – Adicionar um novo pacote NuGet é fácil. Mas cada um aumenta nossa árvore de dependências, potenciais vulnerabilidades de segurança e o custo de manutenção. Esse novo pacote é necessário? É bem mantido?

Performance e Gerenciamento de Recursos

Em C#, é surpreendentemente fácil escrever um código que funciona, mas que no fundo é lento ou vaza recursos. Esses problemas costumam ser invisíveis até o tráfego de produção chegar.

Cuidado com as armadilhas do async/await. – Existe algum async void? É quase sempre uma má ideia fora de event handlers. Estamos usando ConfigureAwait(false) em código de biblioteca quando apropriado? Estamos acidentalmente criando um deadlock ao misturar chamadas blocantes (.Result, .Wait()) com código async?

O descarte de recursos é crucial – Qualquer coisa que implementa IDisposable (conexões de banco de dados, file streams, HttpClient) deve ser descartada. A declaração using (ou a declaração using do C# 8+) é sua melhor amiga. Um using faltando é um vazamento de recurso garantido.

Manuseio eficiente de dados – Existe uma query N+1 escondida em um loop que está chamando uma navigation property do Entity Framework Core? Estamos chamando .ToList() ou .ToArray() prematuramente, puxando muito mais dados para a memória do que o necessário? Estamos usando a estrutura de dados certa para a tarefa (ex: HashSet<T> para buscas rápidas)?

Code review em C# focado em segurança e robustez

Aqui o objetivo é construir um código resiliente que aguenta inputs estranhos e falhas inesperadas.

Nunca confie na entrada de dados – Estamos validando os dados que vêm do mundo externo (requests de API, formulários de usuário)? Estamos usando queries parametrizadas para prevenir SQL injection, ou estamos concatenando strings para montar o SQL? (Por favor, diga que é a primeira opção).

Lide com nulos de forma elegante – Com nullable reference types ativados (e você deveria ativá-los), o compilador ajuda muito. Mas ainda precisamos ficar atentos. O que acontece se um método principal retorna null? O código que o chama lida com isso, ou ele quebra com uma NullReferenceException?

Tratamento de erros e logging – O código está simplesmente engolindo exceções com um bloco catch vazio? Isso é uma bomba-relógio. Devemos tratar as exceções das quais podemos nos recuperar e deixar as não tratadas subirem para um handler global. Estamos registrando informações suficientes para diagnosticar um problema em produção?


O Checklist de Code Review C#

Aqui está um checklist prático e sem enrolação. Você não precisa marcar cada item em todo PR, mas use-o como um guia para estimular seu raciocínio.

✅ Legibilidade & Estilo

  • O código é fácil de entender à primeira vista?
  • Os nomes de variáveis, métodos e classes são claros e sem ambiguidades?
  • Segue as convenções de código existentes do projeto?
  • Os comentários explicam o porquê algo é feito, não o quê é feito?

✅ Arquitetura & Design

  • Essa mudança pertence a esta classe/projeto? (Single Responsibility)
  • O código é testável? As dependências são injetadas?
  • Está super-engenheirado? Existe uma solução mais simples?
  • Introduz novas dependências de terceiros? Se sim, elas se justificam?

✅ Performance & Gerenciamento de Recursos

  • O async/await está sendo usado corretamente (sem async void, sem .Result em tasks)?
  • Objetos IDisposable são descartados corretamente com declarações using?
  • Existe potencial para uma query N+1 ou busca ineficiente de dados (ex: .ToList() prematuro)?
  • As estruturas de dados apropriadas estão sendo usadas para a tarefa (ex: List vs. Dictionary vs. HashSet)?

✅ Segurança

  • Toda entrada externa é validada e sanitizada?
  • Queries parametrizadas são usadas em todo acesso ao banco de dados para prevenir SQLi?
  • Dados sensíveis (senhas, chaves de API) são manuseados de forma segura (ex: não são logados em texto puro)?

✅ Robustez & Tratamento de Erros

  • Valores de retorno ou argumentos null são tratados corretamente? (Especialmente importante se não estiver usando nullable reference types).
  • As exceções são tratadas apropriadamente? São capturadas de forma muito genérica ou silenciadas?
  • Existe logging suficiente para diagnosticar problemas em produção?
  • Casos extremos (edge cases) são considerados (ex: coleções vazias, valores zero, falhas de chamadas de rede)?

✅ Testes

  • Existem testes para a nova lógica?
  • Os testes cobrem o “caminho feliz” assim como os edge cases e cenários de falha?
  • Os testes são fáceis de ler e entender?

Fomentar uma cultura de code review de alta qualidade é um dos melhores investimentos que um time de desenvolvimento pode fazer. Não se trata de adicionar atrito; trata-se de construir um entendimento compartilhado do que é um código “bom” e ajudar uns aos outros a chegar lá. Isso torna o código melhor, e também torna cada dev do time melhor.

Publicado por:
Compartilhe:

Automatize seu Code Review com a Kody

Posts relacionados

Vamos ser sinceros: a maioria de nós tem uma relação de amor e ódio com code reviews. Em um dia bom, são uma colaboração genial que pega bugs e compartilha

Vamos ser sinceros: a maioria de nós tem uma relação de amor e ódio com code reviews. Em um dia bom, são uma colaboração genial que pega bugs e compartilha

Vamos ser sinceros: a maioria de nós tem uma relação de amor e ódio com code reviews. Em um dia bom, são uma colaboração genial que pega bugs e compartilha

@ 2024 Kodus.
Todos os direitos reservados.