Classificação de List<T> em C#: do caos à ordem em 5 minutos
\n\nImagine: você tem uma lista de usuários e precisa exibi-los na tela em ordem alfabética pelo sobrenome. Ou uma lista de produtos — classificar por preço do mais barato ao mais caro. Tarefa familiar? No Stack Overflow, a pergunta «How to Sort a List<T> by a property in the object» acumulou milhares de visualizações — isso significa que este tópico preocupa muitos desenvolvedores.
\n\nNeste artigo, vamos abordar cinco maneiras de classificar uma lista em C#. Você aprenderá como classificar por uma propriedade, vários campos e também como tornar a classificação o mais rápida possível. Vamos lá!
\n\nO que vamos classificar: classe User
\n\nPara os exemplos, vamos usar um modelo de dados simples — um usuário com nome, idade e classificação.
\n\npublic class User\n{\n public string Name { get; set; }\n public int Age { get; set; }\n public double Rating { get; set; }\n\n public override string ToString()\n {\n return $"{Name} ({Age}) — {Rating:F2}";\n }\n}\n\nVamos criar uma lista de teste:
\n\nList<User> users = new List<User>\n{\n new User { Name = "Анна", Age = 30, Rating = 4.5 },\n new User { Name = "Борис", Age = 25, Rating = 3.8 },\n new User { Name = "Виктор", Age = 35, Rating = 4.9 },\n new User { Name = "Галина", Age = 28, Rating = 4.2 }\n};\n\nManeira 1: LINQ OrderBy — a mais simples e elegante
\n\nSe você deseja classificar List<T> por propriedade de objeto rapidamente e sem código extra — use LINQ. O método OrderBy cria uma nova sequência ordenada, sem modificar a lista original. Isso é ideal quando você precisa de uma classificação "em tempo real".
// Classificação por nome (crescente)\nvar sortedByName = users.OrderBy(u => u.Name).ToList();\n\n// Classificação por idade (decrescente)\nvar sortedByAgeDesc = users.OrderByDescending(u => u.Age).ToList();\n\n// Classificação por vários campos: primeiro por idade, depois por classificação\nvar sortedMulti = users\n .OrderBy(u => u.Age)\n .ThenBy(u => u.Rating)\n .ToList();\n\nVantagens: legibilidade, encadeamento de classificações, funciona com qualquer tipo de propriedade.
\nDesvantagens: cria uma nova lista (memória adicional).
Maneira 2: List.Sort com delegado Comparison — classificação no local
\n\nSe você precisa classificar uma lista em C# sem criar uma cópia (economia de memória), use o método Sort com uma expressão lambda. Esta maneira modifica a coleção original.
// Classificação por nome (no local)\nusers.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal));\n\n// Classificação por idade (decrescente)\nusers.Sort((a, b) => b.Age.CompareTo(a.Age));\n\n// Classificação por classificação\nusers.Sort((a, b) => a.Rating.CompareTo(b.Rating));\n\nVantagens: não cria um novo objeto, mais rápido para listas grandes.
\nDesvantagens: menos legível em classificações complexas.
Maneira 3: Implementação de IComparable — classificação "pronta para uso"
\n\nSe sua classe deve sempre ser classificada pelo mesmo campo (por exemplo, pelo nome), implemente a interface IComparable<T>. Então, List.Sort() funcionará sem argumentos.
public class User : IComparable<User>\n{\n // ... propriedades do exemplo acima ...\n\n public int CompareTo(User other)\n {\n if (other == null) return 1;\n return string.Compare(this.Name, other.Name, StringComparison.Ordinal);\n }\n}\n\n// Uso\nusers.Sort(); // automaticamente por nome\n\nVantagens: classificação natural para lógica de negócios.
\nDesvantagens: define rigidamente uma regra — para outros campos, será necessário escrever lógica separada.