Ordenación de List<T> en C#: del caos al orden en 5 minutos
\n\nImagine: tiene una lista de usuarios y necesita mostrarlos en pantalla en orden alfabético por apellido. O una lista de productos: ordenarlos por precio de menor a mayor. ¿Le suena familiar? En Stack Overflow, la pregunta «How to Sort a List<T> by a property in the object» ha acumulado miles de visitas, lo que significa que este tema preocupa a muchos desarrolladores.
\n\nEn este artículo, analizaremos cinco formas de ordenar una lista en C#. Aprenderá a ordenar por una propiedad, por varios campos y también cómo hacer que la ordenación sea lo más rápida posible. ¡Comencemos!
\n\nQué vamos a ordenar: la clase User
\n\nPara los ejemplos, tomaremos un modelo de datos simple: un usuario con nombre, edad y calificación.
\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\nCreemos una lista de prueba:
\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\nForma 1: LINQ OrderBy: la más simple y elegante
\n\nSi desea ordenar List<T> por una propiedad de objeto de forma rápida y sin código adicional, use LINQ. El método OrderBy crea una nueva secuencia ordenada sin modificar la lista original. Es ideal cuando necesita una ordenación «sobre la marcha».
// Ordenación por nombre (ascendente)\nvar sortedByName = users.OrderBy(u => u.Name).ToList();\n\n// Ordenación por edad (descendente)\nvar sortedByAgeDesc = users.OrderByDescending(u => u.Age).ToList();\n\n// Ordenación por varios campos: primero por edad, luego por calificación\nvar sortedMulti = users\n .OrderBy(u => u.Age)\n .ThenBy(u => u.Rating)\n .ToList();\n\nVentajas: legibilidad, cadenas de ordenación, funciona con cualquier tipo de propiedad.
\nDesventajas: crea una nueva lista (memoria adicional).
Forma 2: List.Sort con delegado Comparison: ordenación in situ
\n\nSi necesita ordenar una lista en C# sin crear una copia (ahorro de memoria), use el método Sort con una expresión lambda. Esta forma modifica la colección original.
// Ordenación por nombre (in situ)\nusers.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal));\n\n// Ordenación por edad (descendente)\nusers.Sort((a, b) => b.Age.CompareTo(a.Age));\n\n// Ordenación por calificación\nusers.Sort((a, b) => a.Rating.CompareTo(b.Rating));\n\nVentajas: no crea un nuevo objeto, más rápido para listas grandes.
\nDesventajas: menos legible en ordenaciones complejas.
Forma 3: Implementación de IComparable: ordenación «lista para usar»
\n\nSi su clase siempre debe ordenarse por el mismo campo (por ejemplo, por nombre), implemente la interfaz IComparable<T>. Entonces, List.Sort() funcionará sin argumentos.
public class User : IComparable<User>\n{\n // ... propiedades del ejemplo anterior ...\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(); // automáticamente por nombre\n\nVentajas: ordenación natural para la lógica de negocio.
\nDesventajas: define una regla fija: para otros campos, deberá escribir lógica separada.