En la última semana hemos estado en freazing por un evento de la empresa, por lo que hemos tenido un pequeño periodo de relax, así que me puse a leer blogs de tecnología para hacer creer a mi mente que estoy trabajando, y me puse a hacer implementaciones de esos códigos para hacer creer a mis jefes que estoy trabajando XD.

Bueno el cuento es que encontré una palabra reservada muy interesante que se puede utilizar para todas esas veces que se hace un arreglo temporal para poder recorrerlo, es la directiva yield, que permite disminuir en algunas ocasiones la cantidad de llamados que se hace a una rutina… acabo de leer lo que escribí y no entendí nada… así que mejor un ejemplo.

Supongamos que queremos imprimir una lista de números de 1 a 20, y queremos imprimir por pantalla los pares, (esto es un ejemplo de juguete así que no es nada real), supongamos que hacemos una función que entrega solamente los pares y luego los recorremos imprimiendo los pares (denuevo, aplicación de juguete, solo para mostrar como funciona el yield), la aplicación quedaría algo así.

Función que entrega los números pares en un IEnumerable para poder recorrerlo.

Blog Post Yield 1Con esto obtenemos un listado de enteros que son todos pares en base a una entrada.

Si ejecutamos la siguiente sentencia main:

Blog Post Yield 2Obtenemos un listado enumerable de 1 a 20, lo pasamos y lo dejamos en resultado lo recorremos e imprimimos por pantalla el resultado, de las 2 funciones obtenemos el siguiente resultado

Recorriendo Item: 12
Agregando Item: 12
Recorriendo Item: 13
Recorriendo Item: 14
Agregando Item: 14
Recorriendo Item: 15
Recorriendo Item: 16
Agregando Item: 16
Recorriendo Item: 17
Recorriendo Item: 18
Agregando Item: 18
Recorriendo Item: 19
Recorriendo Item: 20
Agregando Item: 20
2
4
6
8
10
12
14
16
18
20

Recorremos la lista completa la entregamos y luego la recorremos denuevo para imprimir los resultados.

Ahora usemos el yield, para que notemos la diferencia.

Blog Post Yield 3Es básicamente lo mismo pero retornamos con yield cada uno de los items en lugar de meterlos a una lista, esto produce algo muy interesante si ejecutamos el siguiente main.

Blog Post Yield 4Lo interesante aparece al ejecutar la salida, esta nos da el siguiente resultado por consola.

Recorriendo Item: 1
Recorriendo Item: 2
Yield de Item: 2
2
Recorriendo Item: 3
Recorriendo Item: 4
Yield de Item: 4
4
Recorriendo Item: 5
Recorriendo Item: 6
Yield de Item: 6
6
Recorriendo Item: 7
Recorriendo Item: 8
Yield de Item: 8
8
Recorriendo Item: 9
Recorriendo Item: 10
Yield de Item: 10
10
Recorriendo Item: 11
Recorriendo Item: 12
Yield de Item: 12
12
Recorriendo Item: 13
Recorriendo Item: 14
Yield de Item: 14
14
Recorriendo Item: 15
Recorriendo Item: 16
Yield de Item: 16
16
Recorriendo Item: 17
Recorriendo Item: 18
Yield de Item: 18
18
Recorriendo Item: 19
Recorriendo Item: 20
Yield de Item: 20
20

Se ve que se recorre el ítem y que por cada uno de los elementos sale del ciclo hasta ejecutar la sentencia del bloque foreach.

Cuando se nota la diferencia sustancialmente?, cuando ejecutamos la sentencia con un break por ejemplo, comparemos las salidas de este código

Blog Post Yield 5Como se ve se recorre con el sistema con yield y con el sistema de guardar en una lista. Entrega el siguiente resultado.

Recorriendo Item: 1
Recorriendo Item: 2
Agregando Item: 2
Recorriendo Item: 3
Recorriendo Item: 4
Agregando Item: 4
Recorriendo Item: 5
Recorriendo Item: 6
Agregando Item: 6
Recorriendo Item: 7
Recorriendo Item: 8
Agregando Item: 8
Recorriendo Item: 9
Recorriendo Item: 10
Agregando Item: 10
Recorriendo Item: 11
Recorriendo Item: 12
Agregando Item: 12
Recorriendo Item: 13
Recorriendo Item: 14
Agregando Item: 14
Recorriendo Item: 15
Recorriendo Item: 16
Agregando Item: 16
Recorriendo Item: 17
Recorriendo Item: 18
Agregando Item: 18
Recorriendo Item: 19
Recorriendo Item: 20
Agregando Item: 20
2
4
6
8
10
Recorriendo Item: 1
Recorriendo Item: 2
Yield de Item: 2
2
Recorriendo Item: 3
Recorriendo Item: 4
Yield de Item: 4
4
Recorriendo Item: 5
Recorriendo Item: 6
Yield de Item: 6
6
Recorriendo Item: 7
Recorriendo Item: 8
Yield de Item: 8
8
Recorriendo Item: 9
Recorriendo Item: 10
Yield de Item: 10
10

Para la primera parte se recorre el listado completo y luego ese resultado se recorre solo hasta el número 10, por otro lado la llamada con yield solo llega revisando hasta el número 10, y no ejecuta el código para los siguientes números… es una maravilla, uno se puede ahorrar muchas iteraciones de código.

Pero claro viene con una desventaja, si se vuelve a utilizar en una iteración el mismo enumerador, vuelve a ejecutar todas las sentencia.

Eso, si usted no lo encuentra maravilloso y llora con esta palabra reservada, usted no tiene corazón.