C#Intermedio25 oct 2025
El 'finally' que se fue de vacaciones: Iteradores y la Disposición Olvidada
snippet.c#
using System;
using System.Collections.Generic;
public class Program
{
public static IEnumerable<string> GetData()
{
try
{
yield return "FirstItem";
Console.WriteLine("Inside try, after first yield.");
yield return "SecondItem";
Console.WriteLine("Inside try, after second yield.");
}
finally
{
Console.WriteLine("Finally block executed! Cleanup complete.");
}
}
public static void Main(string[] args)
{
// Obtenemos el enumerador directamente, como un aventurero sin mapa.
var enumerator = GetData().GetEnumerator();
// Consumimos solo el primer elemento y luego nos vamos.
if (enumerator.MoveNext())
{
Console.WriteLine($"Consumed: {enumerator.Current}");
}
// ¡Oops! Olvidamos cerrar la puerta o liberar los recursos.
// ¿El 'finally' se ejecutó? ¡Averigüémoslo!
Console.WriteLine("\nMain method finished. Did 'finally' run?");
}
}¿Qué crees que imprime?
✅ Salida Esperada
Consumed: FirstItem
Finally block executed! Cleanup complete.
Main method finished. Did 'finally' run?⚠️ Salida Real
Consumed: FirstItem
Main method finished. Did 'finally' run?¿Por qué pasa esto?
¡Ah, el misterio de los iteradores y el `finally`! Pensarías que un bloque `finally` es como tu mamá 🤰: ¡siempre aparece para limpiar, pase lo que pase! Pero en el mundo de los iteradores (`yield return`), `finally` tiene sus propias reglas de juego. 🎮
Aquí la clave es la **disposición del enumerador**. Cuando usas `foreach`, C# es tu amable mayordomo y se asegura de llamar a `Dispose()` en el enumerador. Y es precisamente esa llamada a `Dispose()` la que activa el bloque `finally` del iterador. 🎉
Pero, ¿qué pasa si eres un *rebelde* y obtienes el enumerador manualmente (`GetData().GetEnumerator()`) y luego... ¡lo abandonas a su suerte! 😱 Si no lo consumes por completo o no llamas a `enumerator.Dispose()` explícitamente, el pobre `finally` se queda esperando, sin ejecutar su valiosa limpieza. Es como dejar la fiesta a medias y que la persona que puso la casa se quede con todo el desorden. 🧹 Por eso, nuestro `finally` nunca se ejecutó. ¡Recuerda siempre limpiar tus recursos! ♻️
Conceptos relacionados
iteratorsresource-managementIDisposable