Eliminación de Elementos en Listas Usando Criterios en C#

Clase 23 de 32Fundamentos de C# con NET Core 2.1

Resumen

Aprende a eliminar elementos de una lista en C# con precisión y buenas prácticas. Verás cómo borrar por referencia, comprender el rol de getHashCode para que el framework identifique el objeto, y aplicar criterios con predicate y delegados para remover múltiples coincidencias de forma segura.

¿Cómo remover por referencia y verificar el resultado?

Borrar por referencia es directo: pasas el objeto exacto que agregaste a la colección y el framework lo localiza y lo elimina.

  • Crear un curso temporal con datos claros.
  • Adicionar a la colección de cursos.
  • Imprimir antes y después para validar el cambio.
var cursoTemporal = new Curso {
    Nombre = "101 vacacional",
    Jornada = Jornada.Noche
};

escuela.Cursos.Adicionar(cursoTemporal);
Console.WriteLine("Antes de remover.");
// ... imprimir colección

escuela.Cursos.Remover(cursoTemporal);
Console.WriteLine("Después de remover.");
// ... imprimir colección

¿Qué valida la referencia al remover?

  • Se pasa la misma instancia que se agregó.
  • El framework compara identidad y elimina la coincidencia.
  • Es útil cuando conservas la referencia del objeto.

¿Qué pasa si ya no tengo la referencia?

  • No siempre puedes guardar todas las referencias.
  • Necesitas otros métodos: por índice, por rango o por criterio.

¿Qué hace getHashCode y por qué el framework encuentra el objeto?

Imprimir el hash del objeto ayuda a entender cómo se localiza internamente. El hash es un entero que sirve como identificador para búsquedas rápidas.

Console.WriteLine($"Hash del curso: {cursoTemporal.GetHashCode()}");
  • Devuelve un entero: puede ser negativo o positivo de cero coma dos mil millones.
  • La probabilidad de colisión es mínima, pero existe.
  • No siempre conviene depender del hash para borrar por criterio.

¿Por qué no usar solo el hash como criterio?

  • Puede haber colisiones, aunque raras.
  • No expresa la intención de negocio (por ejemplo, borrar por Nombre).
  • Mejor usar un criterio declarativo con predicate.

¿Qué otras opciones ofrece remove?

  • Remover por índice: elimina el elemento en una posición.
  • Remover por rango: elimina un bloque continuo.
  • Remover todo por criterio: usa un predicate para decidir qué borrar.

¿Cómo borrar por criterio con predicate y delegados?

Cuando pierdes la referencia del objeto, puedes borrar por condición. Para ello, usa un delegado tipo Predicate<Curso> que reciba un Curso y devuelva bool.

// Definir el algoritmo como método (convención: mayúscula inicial en métodos)
bool Predicado(Curso curso) => curso.Nombre == "301"; // "trescientos uno"

// Encapsular el algoritmo en un delegado
a.Predicate<Curso> miAlgoritmo = Predicado;

// Remover todos los cursos cuyo nombre sea "301"
escuela.Cursos.RemoveAll(miAlgoritmo);
  • Esto es encapsulación de algoritmos: pasas “qué borrar” como función.
  • El delegado garantiza la firma correcta: entrada Curso, salida bool.
  • El elemento que devuelva true se borra; false se conserva.

¿Cómo asegura un delegado la firma del método?

Un delegado especifica tipos de entrada y salida. Si no coinciden, no compila.

// Ejemplo que NO cumple: devuelve int en lugar de bool
int PredicadoMalHecho(Curso curso)
{
    return 301; // Error: la firma no coincide con Predicate<Curso>
}

// Ejemplo que cumple: devuelve bool y recibe Curso
bool PredicadoBien(Curso curso)
{
    return curso.Nombre == "301";
}
  • Evita pasar “cualquier función” que rompa el algoritmo.
  • Mejora la seguridad y claridad del código.

¿Qué ventajas tiene remover por criterio?

  • Expresa reglas de negocio: por nombre, jornada u otros campos.
  • Evita depender de referencias perdidas.
  • Facilita pruebas: el criterio es una función aislada.

¿Te gustaría ver formas más limpias de escribir el algoritmo con expresiones y funciones en línea? Deja tus preguntas y comenta qué criterio de borrado necesitas modelar.