CSharp: Colecciones y LINQ
Domina colecciones genéricas y LINQ en C# para manipular y consultar datos eficientemente en aplicaciones modernas.
Aprende CSharp GRATIS y certifícateColecciones y LINQ en C#
Las colecciones en C# representan uno de los pilares fundamentales para el manejo eficiente de datos en aplicaciones modernas. A diferencia de los arrays tradicionales, las colecciones ofrecen flexibilidad dinámica y funcionalidades avanzadas que permiten almacenar, organizar y manipular conjuntos de elementos de manera más sofisticada.
Fundamentos de las colecciones
El namespace System.Collections.Generic proporciona las estructuras de datos más utilizadas en el desarrollo profesional. Estas colecciones están tipadas, lo que significa que garantizan la seguridad de tipos en tiempo de compilación y ofrecen mejor rendimiento que sus contrapartes no genéricas.
Las colecciones genéricas más importantes incluyen List, Dictionary<TKey, TValue>, HashSet y Queue. Cada una está diseñada para escenarios específicos y ofrece diferentes características de rendimiento según las operaciones que necesites realizar.
// Declaración de diferentes tipos de colecciones
List<string> nombres = new List<string>();
Dictionary<int, string> usuarios = new Dictionary<int, string>();
HashSet<int> numerosUnicos = new HashSet<int>();
Manipulación básica de colecciones
La interfaz ICollection define las operaciones fundamentales que todas las colecciones deben implementar. Esto incluye métodos para agregar, eliminar y verificar la existencia de elementos, así como propiedades para conocer el tamaño de la colección.
List<int> numeros = new List<int> { 1, 2, 3, 4, 5 };
// Operaciones básicas
numeros.Add(6); // Agregar elemento
numeros.Remove(3); // Eliminar elemento específico
bool existe = numeros.Contains(4); // Verificar existencia
int cantidad = numeros.Count; // Obtener tamaño
Las operaciones de búsqueda en colecciones varían según el tipo utilizado. Mientras que List realiza búsquedas lineales, Dictionary<TKey, TValue> y HashSet ofrecen búsquedas en tiempo constante promedio gracias a su implementación basada en tablas hash.
Introducción a LINQ
Language Integrated Query (LINQ) revoluciona la forma de trabajar con colecciones al proporcionar una sintaxis declarativa para consultar y transformar datos. LINQ permite escribir consultas similares a SQL directamente en código C#, haciendo que las operaciones complejas sobre colecciones sean más legibles y mantenibles.
List<int> numeros = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Consulta LINQ para obtener números pares
var numerosPares = from n in numeros
where n % 2 == 0
select n;
La sintaxis de métodos de LINQ utiliza métodos de extensión que se encadenan para crear consultas fluidas. Esta aproximación es especialmente útil cuando necesitas realizar transformaciones complejas o cuando trabajas con expresiones lambda.
// Misma consulta usando sintaxis de métodos
var numerosPares = numeros.Where(n => n % 2 == 0);
// Consulta más compleja con múltiples operaciones
var resultado = numeros
.Where(n => n > 3)
.Select(n => n * 2)
.OrderByDescending(n => n)
.Take(3);
Operadores LINQ fundamentales
Los operadores de filtrado como Where() permiten seleccionar elementos que cumplan condiciones específicas. Estos operadores utilizan predicados (funciones que devuelven bool) para determinar qué elementos incluir en el resultado.
Los operadores de proyección como Select() transforman cada elemento de la colección original en un nuevo formato. Esto es especialmente útil cuando necesitas extraer propiedades específicas o realizar cálculos sobre los datos.
List<string> palabras = new List<string> { "casa", "perro", "gato", "elefante" };
// Filtrar palabras con más de 4 caracteres y convertir a mayúsculas
var palabrasLargas = palabras
.Where(p => p.Length > 4)
.Select(p => p.ToUpper());
Los operadores de agregación como Sum(), Count(), Average() y Max() calculan valores únicos a partir de toda la colección. Estos operadores son fundamentales para generar estadísticas y resúmenes de datos.
List<int> calificaciones = new List<int> { 85, 92, 78, 96, 88 };
double promedio = calificaciones.Average();
int maxima = calificaciones.Max();
int aprobados = calificaciones.Count(c => c >= 80);
Consultas complejas y agrupamiento
El operador GroupBy() organiza elementos en grupos basados en una clave común. Esta funcionalidad es esencial cuando necesitas categorizar datos o realizar análisis por grupos.
List<string> palabras = new List<string> { "casa", "coche", "perro", "gato", "camión" };
// Agrupar palabras por su primera letra
var gruposPorLetra = palabras
.GroupBy(p => p[0])
.Select(g => new { Letra = g.Key, Palabras = g.ToList() });
Las consultas anidadas permiten trabajar con estructuras de datos más complejas, combinando múltiples colecciones o realizando operaciones sobre los resultados de otras consultas.
La evaluación diferida (lazy evaluation) es una característica clave de LINQ que significa que las consultas no se ejecutan hasta que realmente necesitas los resultados. Esto optimiza el rendimiento al evitar procesamiento innecesario.
var consulta = numeros.Where(n => n > 5); // No se ejecuta aquí
// La consulta se ejecuta cuando iteras sobre los resultados
foreach (int numero in consulta)
{
Console.WriteLine(numero);
}
Lecciones de este módulo de CSharp
Lecciones de programación del módulo Colecciones y LINQ del curso de CSharp.
Ejercicios de programación en este módulo de CSharp
Evalúa tus conocimientos en Colecciones y LINQ con ejercicios de programación Colecciones y LINQ de tipo Test, Puzzle, Código y Proyecto con VSCode.