C# - Cinco erros de desenvolvedores ao trabalhar com listas


 Neste artigo vou apresentar cinco erros que geralmente são cometidos por devs C# ao tratar com listas.

No C# as listas são uma estrutura de dados fundamental que todo desenvolvedor utiliza. Elas oferecem uma forma flexível de armazenar e manipular coleções de dados, tornando-as ideais para diversos cenários de programação. No entanto, apesar de sua simplicidade, as listas podem ser a fonte de bugs sutis e problemas de desempenho quando não são usadas corretamente.  

Neste artigo, vou explorar os 5 erros comuns que os desenvolvedores cometem ao trabalhar com listas no C# e como evitá-los, garantindo que seu código seja eficiente e robusto.

Erro 1- Iteração ineficiente em listas grandes

Iterar sobre listas grandes usando loops for ou foreach tradicionais pode ser ineficiente, especialmente quando a lista contém milhares ou até milhões de itens. Desenvolvedores frequentemente ignoram formas melhores de lidar com tais iterações.

Por que é um problema:

Usar loops simples para listas grandes pode levar a um desempenho mais lento, pois cada iteração adiciona sobrecarga. Isso pode se tornar um gargalo em aplicações que dependem fortemente do processamento de grandes coleções, como análise de dados ou aplicações em tempo real.

Como evitar:

Usando a LINQ: O C# oferece métodos LINQ poderosos como Select, Where, Any e All, que são otimizados para trabalhar com coleções. Por exemplo:

var listafiltradas = minhaLista.Where(item => item.IsActive).ToList();

Iteração Paralela: Se a lista for extremamente grande e as operações em cada item forem independentes, você pode usar Parallel.ForEach para paralelizar o processamento:

Parallel.ForEach(minhaListaGrande, item => {
             ProcessarItem(item);
});

Ao escolher a técnica de iteração correta, você pode melhorar significativamente o desempenho da sua aplicação.

Erro 2: Modificar listas enquanto itera

Um erro comum é tentar modificar uma lista (como adicionar ou remover itens) enquanto itera sobre ela usando um loop foreach. Isso pode levar a exceções de tempo de execução como InvalidOperationException.

Por que é um problema:

Modificar uma lista durante a iteração pode interromper a enumeração subjacente, causando comportamento inesperado ou exceções. Por exemplo, tentar remover itens de uma lista dentro de um loop foreach resulta em um erro.

Como evitar:

Use uma Lista Secundária: Quando você precisar remover itens de uma lista durante a iteração, armazene os itens a serem removidos em uma lista secundária e, em seguida, remova-os após o loop:

var itemsARemover = new List<MeuTipo>();

foreach (var item in minhaLista)
{
    if (ShouldRemove(item))
        itemsARemover.Add(item);
}

foreach (var item in itemsARemover)
{
    minhaLista.Remove(item);
}

Use LINQ para Filtragem: Alternativamente, você pode usar LINQ para criar uma nova lista filtrada:


  minhaLista = minhaLista.Where(item => !ShouldRemove(item)).ToList();

Esses métodos evitam erros e tornam seu código mais limpo.

Erro #3: Não Compreender a Capacidade da Lista

A List<T> em C# tem uma propriedade Capacity (Capacidade), que é o número de elementos que a lista pode conter antes de precisar redimensionar. Desenvolvedores frequentemente ignoram a configuração da capacidade, levando a múltiplas operações de redimensionamento à medida que os itens são adicionados.

Por que é um problema:

Quando uma lista excede sua capacidade atual, ela automaticamente aumenta sua capacidade criando um novo array maior e copiando os elementos para ele. Esse redimensionamento pode impactar o desempenho se for feito frequentemente com listas grandes.

Como evitar:

Defina a Capacidade Inicial: Se você souber o número aproximado de itens que serão adicionados à lista, defina a capacidade inicial para evitar múltiplos redimensionamentos:

var minhaLista = new List<int>(1000);   // Define a capacidade inicial para 1000.

Use EnsureCapacity: Se o tamanho da lista for dinâmico, mas você quiser evitar o redimensionamento até um certo número, use EnsureCapacity:

minhaLista.EnsureCapacity(5000);

Ao gerenciar a capacidade da lista, você pode tornar suas operações com listas mais eficientes.

Erro #4: Usar List em Vez de ReadOnlyCollection

Desenvolvedores frequentemente expõem List<T> diretamente de suas classes quando não pretendem que a lista seja modificada por código externo. Isso pode levar a alterações não intencionais na lista.

Por que é um problema:

Expor List<T> diretamente possibilita que qualquer consumidor de sua classe adicione, remova ou modifique elementos, o que pode ser contra as intenções de design. Isso pode causar problemas de integridade de dados.

Como evitar:

Use ReadOnlyCollection: Embrulhe sua lista em um ReadOnlyCollection<T> antes de expô-la:


 private readonly List<string> _nomes = new List<string>();
 public ReadOnlyCollection<string> Nomes => _nomes.AsReadOnly();

Use Coleções Imutáveis: Em cenários onde você deseja imutabilidade completa, use o recurso ImmutableList<T> do System.Collections.Immutable:


  var
listaImutavel = ImmutableList.CreateRange(minhaLista);

Essas opções garantem que sua lista seja modificada apenas internamente, mantendo uma melhor encapsulamento.

Erro #5: Técnicas de Classificação Ineficientes

Classificar listas é uma tarefa comum, mas a lógica de classificação personalizada pode ser menos eficiente em comparação com métodos incorporados como List<T>.Sort().

Por que é um problema:

Escrever lógica de classificação personalizada pode ser propenso a erros e menos otimizado do que os métodos nativos fornecidos pelo .NET 8, levando a um desempenho de classificação mais lento.

Como evitar:

Use List<T>.Sort() para classificação no Local: Este método é altamente otimizado e deve ser sua primeira opção para classificar uma lista no local:


 minhaLista.Sort((a, b) => a.Property.CompareTo(b.Property));

Use LINQ OrderBy() para Criar Cópias Classificadas: Se você quiser preservar a lista original enquanto cria uma versão classificada:


var listaOrdenada = minhaLista.OrderBy(item => item.Property).ToList();

Escolher o método de classificação certo ajuda a manter seu código conciso e eficiente.

Trabalhar com listas no C# é crucial para muitas aplicações, mas mesmo desenvolvedores experientes podem cair em armadilhas comuns. Ao entender esses 5 erros e como evitá-los, você pode escrever código mais eficiente, de fácil manutenção e menos propenso a erros.

Aplique essas dicas em seus projetos e você verá melhorias tanto no desempenho quanto na confiabilidade

E estamos conversados...  

"Porque pela graça sois salvos, por meio da fé; e isto não vem de vós, é dom de Deus. Não vem das obras, para que ninguém se glorie;"
Efésios 2:8,9

Referências:


José Carlos Macoratti