yield break y terminación anticipada
Detenga la iteración de forma condicional.
yield break y terminación anticipada es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.
Detener un iterador antes de tiempo
A veces querrá que un iterador deje de producir valores antes de alcanzar el final natural. La instrucción yield break termina la secuencia inmediatamente, como un return para los iteradores.
yield break básico
yield break termina el iterador. No se producen más valores y finaliza el bucle foreach que lo consume.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> UpToFive()
{
for (int i = 1; i <= 100; i++)
{
if (i > 5) yield break;
yield return i;
}
}
public static void Main()
{
foreach (var n in UpToFive())
Console.WriteLine(n);
}
}Tomar elementos mientras se cumpla una condición
Un patrón habitual consiste en producir elementos solo mientras una condición sea verdadera y detenerse después. yield break hace que esto resulte sencillo.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> WhileSmall(IEnumerable<int> nums)
{
foreach (var n in nums)
{
if (n >= 10) yield break;
yield return n;
}
}
public static void Main()
{
foreach (var n in WhileSmall(new[] { 2, 4, 8, 12, 3 }))
Console.WriteLine(n);
}
}Cláusulas de guarda con yield break
Puede usar yield break al principio de un iterador como cláusula de guarda. Si la entrada está vacía o no es válida, no devuelva ningún elemento.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
static IEnumerable<string> Lines(string text)
{
if (string.IsNullOrEmpty(text)) yield break;
foreach (var line in text.Split('\n'))
yield return line;
}
public static void Main()
{
foreach (var l in Lines("a\nb\nc"))
Console.WriteLine(l);
Console.WriteLine("empty count: " + Lines("").Count());
}
}Limitar la cantidad de resultados
Use un contador junto con yield break para limitar la cantidad de elementos que produce un iterador, incluso a partir de un origen extenso.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> Take(IEnumerable<int> source, int max)
{
int count = 0;
foreach (var item in source)
{
if (count++ >= max) yield break;
yield return item;
}
}
public static void Main()
{
foreach (var n in Take(new[] { 1, 2, 3, 4, 5 }, 3))
Console.WriteLine(n);
}
}break de quien llama frente a yield break
Una secuencia puede terminar de dos formas. Quien llama puede dejar de solicitar elementos mediante break, o el iterador puede dejar de producirlos mediante yield break. Ambas formas terminan el bucle, pero por motivos diferentes.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> Counting()
{
int i = 1;
while (true) yield return i++;
}
public static void Main()
{
// Caller decides to stop with break
foreach (var n in Counting())
{
if (n > 3) break;
Console.WriteLine(n);
}
}
}yield break solo termina el iterador actual
yield break sale del método iterador en el que aparece, no de ningún bucle externo de quien llama. El control vuelve a quien estaba enumerando.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> Bounded(IEnumerable<int> nums, int limit)
{
foreach (var n in nums)
{
if (n > limit) yield break; // ends Bounded only
yield return n;
}
}
public static void Main()
{
var result = Bounded(new[] { 1, 2, 9, 3 }, 5);
Console.WriteLine("iterator created, still running");
foreach (var n in result) Console.WriteLine(n);
}
}No hay yield return después de yield break
Una vez que se ejecuta yield break, el iterador ha terminado. El código que esté físicamente después de esa instrucción en la misma ruta ya no puede producir valores.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> Demo(bool stopEarly)
{
yield return 1;
if (stopEarly) yield break;
yield return 2;
yield return 3;
}
public static void Main()
{
Console.WriteLine("stopEarly = true:");
foreach (var n in Demo(true)) Console.WriteLine(n);
Console.WriteLine("stopEarly = false:");
foreach (var n in Demo(false)) Console.WriteLine(n);
}
}Combinar filtrado y detención anticipada
Puede filtrar y terminar en el mismo iterador: omita algunos valores, produzca otros y detenga completamente la ejecución cuando aparezca un valor centinela.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> UntilZero(IEnumerable<int> nums)
{
foreach (var n in nums)
{
if (n == 0) yield break; // stop at sentinel
if (n < 0) continue; // skip negatives
yield return n;
}
}
public static void Main()
{
foreach (var n in UntilZero(new[] { 3, -1, 5, 0, 9 }))
Console.WriteLine(n);
}
}Bloques de yield break y finally
Si su iterador contiene un try/finally, el bloque finally sigue ejecutándose cuando yield break termina la secuencia. Esto garantiza tareas de limpieza, como cerrar recursos.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> WithCleanup()
{
try
{
yield return 1;
yield break;
}
finally
{
Console.WriteLine("cleanup ran");
}
}
public static void Main()
{
foreach (var n in WithCleanup())
Console.WriteLine(n);
}
}Pruébelo usted mismo
Combine el filtrado y la terminación anticipada: produzca números positivos con yield, pero deténgase por completo en cuanto su suma acumulada supere un presupuesto.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> WithinBudget(IEnumerable<int> nums, int budget)
{
int spent = 0;
foreach (var n in nums)
{
if (n <= 0) continue;
if (spent + n > budget) yield break;
spent += n;
yield return n;
}
}
public static void Main()
{
foreach (var n in WithinBudget(new[] { 3, -2, 4, 5, 1 }, 10))
Console.WriteLine(n);
}
}Comprobación rápida
Recuerde la función de yield break.
Resumen
yield break termina un iterador antes de tiempo.
- Funciona como un
returnsin valor para los iteradores. - Úselo para implementar lógica de toma mientras se cumpla una condición, protecciones y límites de cantidad.
- Solo termina el iterador, no el bucle del código que lo llama.
- Los bloques
finallysiguen ejecutándose, lo que garantiza la limpieza.
Preguntas frecuentes
¿La lección «yield break y terminación anticipada» es gratis?
Sí — el texto completo de «yield break y terminación anticipada» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.
¿Qué aprenderé en «yield break y terminación anticipada»?
Detenga la iteración de forma condicional. Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar C# Academy?
No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «yield break y terminación anticipada»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de C# Academy?
Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Métodos iteradores con yield return
- yield break y terminación anticipada
- Semántica de la evaluación diferida
- Enumerables personalizados