Principais erros de desenvolvedores C# iniciantes: nível avançado
A transição de escrever aplicações de console simples para criar soluções robustas, escaláveis e de alto desempenho em C# é um desafio. Muitos desenvolvedores, após dominarem a sintaxe, encontram "armadilhas" que transformam o código em uma fonte de bugs e queda de desempenho. Neste artigo, analisaremos 4 erros principais que desenvolvedores C# iniciantes cometem em nível avançado e mostraremos como evitá-los.
1. Trabalho incorreto com assincronia (async/await)
Um dos problemas mais comuns é a compreensão incorreta do modelo async/await. Um erro típico é bloquear o código assíncrono com .Result ou .Wait(). Isso não apenas prejudica o desempenho, mas também pode levar a um deadlock.
Exemplo de erro:
public class BadAsyncExample{ public string GetData() { // Bloqueia a thread, aguardando o resultado da operação assíncrona return GetDataAsync().Result; // Deadlock! }
private async Task<string> GetDataAsync() { await Task.Delay(1000); return "Data"; }}Abordagem correta:
public class GoodAsyncExample{ public async Task<string> GetDataAsync() { await Task.Delay(1000); return "Data"; }
// O código chamador deve ser assíncrono do início ao fim public async Task ProcessAsync() { var data = await GetDataAsync(); Console.WriteLine(data); }}Use ConfigureAwait(false) no código de biblioteca para evitar capturar o contexto de sincronização e reduzir o risco de deadlocks.
2. Abuso de LINQ e perda de desempenho
LINQ é uma ferramenta poderosa, mas seu uso incorreto pode levar a múltiplas iterações na coleção e queda de desempenho. O principal erro é não entender a execução adiada (deferred execution).
Exemplo de erro:
var numbers = Enumerable.Range(1, 1000);
// Filtra a coleçãovar filtered = numbers.Where(n => n % 2 == 0);
// Iteração múltiplavar count = filtered.Count(); // 1ª iteraçãovar sum = filtered.Sum(); // 2ª iteraçãovar list = filtered.ToList(); // 3ª iteraçãoCada chamada a Count(), Sum() ou ToList() executa novamente todo o pipeline do LINQ. Isso é especialmente crítico ao trabalhar com bancos de dados (Entity Framework), onde cada iteração é uma nova consulta SQL.
Abordagem correta:
var numbers = Enumerable.Range(1, 1000);
// Materializa o resultado uma única vezvar filtered = numbers.Where(n => n % 2 == 0).ToList();
// Agora trabalhamos com a lista prontavar count = filtered.Count;var sum = filtered.Sum();Sempre materialize o resultado de uma consulta LINQ (ToList(), ToArray()) se planeja usá-lo mais de uma vez.
3. Ignorar a segurança contra nulos e NullReferenceException
NullReferenceException é um companheiro eterno do desenvolvedor C#. Com o surgimento dos nullable reference types no C# 8.0, temos ferramentas para combater esse problema, mas muitos iniciantes as ignoram.
Exemplo de erro:
public class User{ public string Name { get; set; } // Pode ser null!}
public void PrintUserName(User user){ Console.WriteLine(user.Name.Length); // NullReferenceException, se user == null ou Name == null}Abordagem correta:
#nullable enablepublic class User{ public string Name { get; set; } = string.Empty; // Não permite null public string? MiddleName { get; set; } // Indica explicitamente que pode ser null}