Mis dos centavos en la palabra clave yield en C #

La palabra clave yield, introducida por primera vez en C # 2.0, T devuelve un objeto que implementa la interfaz IEnumerable. La interfaz IEnumerable expone un IEnumerator que puede usarse para iterar una colección no genérica usando un bucle foreach en C #. Puede utilizar la palabra clave yield para indicar que el método o un descriptor de acceso get en el que se ha utilizado es un iterador.

Hay dos formas en las que puede utilizar la palabra clave yield: utilizando las declaraciones "yield return" y "yield break". La sintaxis de ambos se muestra a continuación.

yield return ;

yield break;

¿Por qué debería utilizar la palabra clave de rendimiento?

La palabra clave yield puede realizar una iteración de estado completo sin la necesidad de crear una colección temporal. En otras palabras, cuando se usa la declaración "rendimiento de retorno" dentro de un iterador, no es necesario crear una colección temporal para almacenar datos antes de que regresen. Puede aprovechar la declaración de rendimiento de retorno para devolver cada elemento de la colección de uno en uno, y puede utilizar la declaración de "rendimiento de rendimiento" con iteradores en un método o un descriptor de acceso get.

Tenga en cuenta que el control se devuelve a la persona que llama cada vez que se encuentra y ejecuta la instrucción "yield return". Lo más importante es que con cada una de estas llamadas, la información del estado del destinatario de la llamada se conserva para que la ejecución pueda continuar inmediatamente después de la declaración de rendimiento cuando el control regrese.

Veamos un ejemplo. El siguiente fragmento de código ilustra cómo se puede utilizar la palabra clave yield para devolver un número de Fibonacci. El método acepta un número entero como argumento que representa el recuento de los números de Fibonacci a generar.

static IEnumerable GenerateFibonacciNumbers(int n)

       {

           for (int i = 0, j = 0, k = 1; i < n; i++)

          {

               yield return j;

               int temp = j + k;

               j = k;

               k = temp;

           }

       }

Como se muestra en el fragmento de código anterior, la declaración "yield return j;" devuelve los números de Fibonacci uno por uno sin salir del ciclo "for". En otras palabras, se conserva la información del estado. Así es como se puede llamar al método GenerateFibonacciNumbers.

foreach (int x in GenerateFibonacciNumbers(10))

   {

       Console.WriteLine(x);

   }

Como puede observar, no es necesario crear una lista o matriz intermedia para contener los números de fibonacci que deben generarse y devolverse a la persona que llama.

Tenga en cuenta que debajo de las cubiertas, la palabra clave yield crea una máquina de estado para mantener la información de estado. El MSDN dice: "Cuando se alcanza una declaración de retorno de rendimiento en el método de iterador, se devuelve la expresión y se conserva la ubicación actual en el código. La ejecución se reinicia desde esa ubicación la próxima vez que se llama a la función del iterador".

Otra ventaja de usar la palabra clave yield es que los artículos que se devuelven se crean solo a pedido. Como ejemplo, el siguiente descriptor de acceso get devuelve los números pares entre 1 y 10.

public static IEnumerable EvenNumbers

       {

           obtener

           {

               para (int i = 1; i <= 10; i ++)

               {

                   si ((i% 2) == 0)

                   rendimiento rendimiento i;

               }

           }

       }

Puede acceder a la propiedad estática EvenNumbers para mostrar los números pares entre 1 y 10 en la ventana de la consola usando el fragmento de código que se proporciona a continuación.

foreach (int i in EvenNumbers)

     {

         Console.WriteLine(i);

     }

Puede utilizar la declaración "límite de rendimiento" dentro de un iterador cuando no hay más valores para devolver. La declaración de "límite de rendimiento" se utiliza para terminar la enumeración.

public IEnumerable GetData(IEnumerable items)

{

   if (null == items)

       yield break;

   foreach (T item in items)

       yield return item;

}

Consulte la lista de códigos anterior. Observe cómo se realiza una verificación para ver si el parámetro "elementos" es nulo. Cuando invoca el método GetData () dentro de un iterador y con nulo como parámetro, el control simplemente regresa al llamador sin que se devuelva ningún valor.

Puntos para recordar

Cuando trabaje con la palabra clave de rendimiento, debe tener en cuenta estos puntos:

  • No puede tener la declaración de retorno de rendimiento en un bloque try-catch aunque puede tenerla dentro de un bloque try-finalmente
  • No puede tener la declaración de ruptura de rendimiento dentro de un bloque finalmente
  • El tipo de retorno del método donde se ha utilizado el rendimiento debe ser IEnumerable, IEnumerable, IEnumerator o IEnumerator
  • No puede tener un parámetro ref o out en su método en el que se ha utilizado el rendimiento
  • No puede utilizar las declaraciones de "rendimiento de rendimiento" o "límite de rendimiento" dentro de métodos anónimos.
  • No puede usar las declaraciones "rendimiento de rendimiento" o "límite de rendimiento" dentro de los métodos "inseguros", es decir, los métodos que están marcados con la palabra clave "inseguro" para denotar un contexto inseguro.