Code Review em C#: não apenas uma formalidade, mas a salvação da produção
\n\nVocê já viu um código que funciona, mas que dá vontade de fechar os olhos? "Números mágicos", loops dentro de loops, async void e null onde não deveria estar. O code review em C# não é um procedimento burocrático, mas a última linha de defesa antes que um bug vá para produção. Ou, pior ainda, antes que seus colegas comecem a dar manutenção no código, amaldiçoando o autor.
Neste artigo, vamos analisar no que realmente prestar atenção ao revisar código C#. Nada de enrolação — apenas casos concretos, antipadrões e exemplos. Se você é júnior, este é seu checklist. Se é sênior, refresque a memória. Vamos nessa.
\n\n1. Null — o principal inimigo do desenvolvedor C#
\n\nO famoso NullReferenceException é a causa de milhões de noites sem dormir. A primeira coisa que verificamos em um code review: proteção contra null.
O que deve acender um alerta?
\n- \n
- Ausência de verificação de
nullantes de acessar propriedades. \n - Retorno de
nullde métodos onde se espera uma coleção. \n - Ignorar contextos anuláveis (
#nullable enable). \n
Ruim:
\npublic string GetUserName(User user)\n{\n return user.Name.ToUpper(); // user pode ser null!\n}\n\nBom (C# 8+):
\npublic string GetUserName(User? user)\n{\n return user?.Name?.ToUpper() ?? "Unknown";\n}\n\nDica para code review: exija a ativação de Nullable em novos projetos. Não é apenas moda, isso evita erros bobos. Code review C# sem verificar nullable é como dirigir sem cinto de segurança.
2. Assincronicidade: async/await sem armadilhas
\n\nProgramação assíncrona em C# é uma ferramenta poderosa, mas quando usada incorretamente, vira uma bomba-relógio. Na revisão, verificamos três pecados capitais.
\n\nPecado nº1: async void
\nMétodos async void não podem ser rastreados — a exceção cai na thread final e mata o processo. Só é permitido para manipuladores de eventos (ex.: botões no WinForms).
Ruim:
\npublic async void LoadDataAsync()\n{\n var data = await _service.GetDataAsync(); // Erro mata o processo\n}\n\nBom:
\npublic async Task LoadDataAsync()\n{\n var data = await _service.GetDataAsync();\n}\n\nPecado nº2: Bloqueio de código assíncrono
\n.Result ou .Wait() em contexto assíncrono é caminho certo para deadlock.
Ruim:
\nvar result = _service.GetDataAsync().Result; // deadlock em aplicações UI\n\nBom:
\nvar result = await _service.GetDataAsync();\n\nPecado nº3: Ausência de CancellationToken
\nOperações longas devem ser canceláveis. Se na assinatura do método não há CancellationToken, pergunte ao autor: "O que acontece se o usuário fechar a aba?"
3. LINQ: beleza ou morte lenta?
\n\nLINQ é elegante. Mas o code review frequentemente revela que por trás da elegância se esconde O(n²) ou múltiplas iterações na coleção.
\n\nErros típicos ao revisar código C# com LINQ:
\n- \n
- Múltiplas iterações:
.Count() > 0+.First()— duas passagens. Use.Any()e.FirstOrDefault(). \n - ToList() esquecido: carregamento preguiçoso pode fazer com que a consulta ao banco seja executada depois que o contexto DataReader já foi fechado. \n
- Where + Select = redundância: se puder usar um único
SelectMany, use. \n
Exemplo que deve acender uma bandeira vermelha:
\nvar result = l