2010-05-14 11 views

Respuesta

6

La construcción yield se utiliza para crear un iterador que puede producir múltiples valores en la serie:

IEnumerable<int> three_numbers() { 
    yield return 1; 
    yield return 2; 
    yield return 3; 
} 
... 
foreach (var i in three_numbers()) { 
    // i becomes 1, 2 and 3, in turn. 
} 
7

El rendimiento es para iteradores.

Le permite procesar una lista en pequeñas golondrinas, lo cual es bueno para listas grandes.

Lo mágico de Yield es que recuerda dónde estás entre invocaciones.

Si no está iterando, no necesita Rendimiento.

21

Use yield cuando devuelve un enumerable, y no tiene todos los resultados en ese momento.

Prácticamente, he utilizado el rendimiento cuando quiero iterar a través de un gran bloque de información (base de datos, archivo plano, etc.), y no quiero cargar todo en la memoria primero. El rendimiento es una buena forma de iterar a través del bloque sin cargar todo a la vez.

1

Rendimiento La devolución continuará el método desde ese punto. Por ejemplo, desea recorrer una matriz o lista y devolver cada elemento a la vez para que la persona que llama procese. Entonces usará retorno de rendimiento. Si desea devolver todo y luego hecho, usted no necesita hacer eso

1

Se explica aquí :

C# Language Reference
yield (C# Reference)

el método llamado devolverá todos los valores individuales para que puedan ser enumerados por la persona que llama.

Esto significa que necesitará usar rendimiento cuando desee que todos los resultados posibles devueltos por una iteración.

6

La palabra clave yield es increíblemente poderosa. Básicamente, le permite devolver rápidamente los objetos IEnumerable y IEnumerator sin codificarlos explícitamente.

Considere un escenario en el que desea devolver la intersección de dos objetos IEnumerable. Aquí es cómo lo haría usando la palabra clave yield.

public static class Program 
{ 
    public static void Main() 
    { 
    IEnumerable<object> lhs = new List<int> { 1, 2, 3, 4, 5 }; 
    IEnumerable<object> rhs = new List<int> { 3, 4, 5, 6, 7 }; 
    foreach (object item in IntersectExample.Intersect(lhs, rhs)) 
    { 
     Console.WriteLine(item); 
     break; 
    } 
    } 
} 

public static class IntersectExample 
{ 
    public static IEnumerable<object> Intersect(IEnumerable<object> lhs, IEnumerable<object> rhs) 
    { 
    var hashset = new HashSet<object>(); 
    foreach (object item in lhs) 
    { 
     if (!hashset.Contains(item)) 
     { 
     hashset.Add(item); 
     } 
    } 
    foreach (object item in rhs) 
    { 
     if (hashset.Contains(item)) 
     { 
     yield return item; 
     } 
    } 
    } 
} 

Es difícil de apreciar hasta que no se dé cuenta de lo que está pasando. Normalmente, cuando se cruzan dos conjuntos, se completa la operación completa antes de devolver el resultado a la persona que llama. Significa que la complejidad del tiempo de ejecución de la operación es O(m + n), donde m y n son los tamaños de las colecciones que se cruzan, independientemente de lo que haga con el resultado posterior. Pero, en mi ejemplo, solo quería elegir el primer elemento del resultado. El uso de un IEnumerable que fue creado por la palabra clave yield hace que sea muy fácil retrasar parte del procesamiento hasta que realmente se requiera. Mi ejemplo se ejecuta en O(m). La alternativa es codificar el IEnumerable y mantener el estado en él manualmente. El poder de la palabra clave yield es que crea esa máquina de estado para usted.

Cuestiones relacionadas