¿Cómo yield
implementa el patrón de lazy loading
?¿Cómo el rendimiento implementa el patrón de carga diferida?
Respuesta
implementación de rendimiento no alcanza el código hasta que sea necesario.
Por ejemplo, este código:
public IEnumerable<int> GetInts()
{
yield return 1;
yield return 2;
yield return 3;
}
realmente compilar en una clase anidada que implementa IEnumerable<int>
y el cuerpo de GetInts()
devolverá una instancia de esa clase.
El uso del reflector se puede ver:
public IEnumerable<int> GetInts()
{
<GetInts>d__6d d__d = new <GetInts>d__6d(-2);
d__d.<>4__this = this;
return d__d;
}
Editar - la adición de más información sobre GetInts
aplicación:
La forma en que esta aplicación hace que sea perezosa se basa en el método Enumerator
MoveNext()
. Cuando se genera la clase anidada enumerable (<GetInts>d__6d
en el ejemplo), tiene un estado y para cada estado se conecta un valor (este es un caso simple, en casos más avanzados, el valor se evaluará cuando el código llegue al estado). Si echamos un vistazo en el código de MoveNext()
<GetInts>d__6d
veremos el estado:
private bool MoveNext()
{
switch (this.<>1__state)
{
case 0:
this.<>1__state = -1;
this.<>2__current = 1;
this.<>1__state = 1;
return true;
case 1:
this.<>1__state = -1;
this.<>2__current = 2;
this.<>1__state = 2;
return true;
case 2:
this.<>1__state = -1;
this.<>2__current = 3;
this.<>1__state = 3;
return true;
case 3:
this.<>1__state = -1;
break;
}
return false;
}
Cuando se le pide al empadronador para el objeto actual que devuelve el objeto que está conectado con el estado actual.
Con el fin de demostrar que el código se evalúa sólo cuando es necesario se puede ver en este ejemplo:
[TestFixture]
public class YieldExample
{
private int flag = 0;
public IEnumerable<int> GetInts()
{
yield return 1;
flag = 1;
yield return 2;
flag = 2;
yield return 3;
flag = 3;
}
[Test]
public void Test()
{
int expectedFlag = 0;
foreach (var i in GetInts())
{
Assert.That(flag, Is.EqualTo(expectedFlag));
expectedFlag++;
}
Assert.That(flag, Is.EqualTo(expectedFlag));
}
}
espero que sea un poco más clara. Recomiendo echar un vistazo al código con Reflector y observar el código compilado a medida que cambia el código de "rendimiento".
Si desea saber más acerca de lo que el compilador está haciendo cuando se utiliza yield return
, compruebe este artículo de Jon Skeet: Iterator block implementation details
Briljant redirige, en realidad. +1 – peSHIr
Básicamente iteradores implementated utilizando yield
declaraciones se compilan en una clase que implementa un state machine.
Si nunca foreach
(= itera y usa) el IEnumerable<T>
devuelto, el código nunca se ejecuta. Y si lo hace, solo se ejecuta el código mínimo necesario para determinar el siguiente valor a devolver, solo para reanudar la ejecución cuando se solicita un próximo valor.
En realidad, puede ver este comportamiento que ocurre cuando usted solo paso tal código en el depurador. Pruébalo al menos una vez: creo que es alentador ver que esto suceda paso a paso.
- 1. Carga diferida, carga diferida y carga ansiosa en el marco de la entidad
- 2. Patrón de repositorio con carga diferida usando POCO
- 3. IQueryable vs. IEnumerable en el patrón de repositorio, carga lenta
- 4. ¿Biblioteca de carga diferida?
- 5. ¿Carga diferida del iframe?
- 6. Carga diferida en Knockout JS
- 7. UITableView optimización de carga diferida
- 8. Carga diferida de los atributos
- 9. nhibernate opciones de carga diferida
- 10. Patrón de iterador en VB.NET (C# utilizaría el rendimiento!)
- 11. ¿El LINQ con un resultado escalar disparar la carga diferida
- 12. Páginas de carga diferida en UIScrollView
- 13. Carga diferida de imágenes con degradación (JavaScript)
- 14. imágenes de carga diferida y SEO
- 15. Carga diferida de TreeView en .NET
- 16. Carga diferida de Hibernate en objetos separados
- 17. Patrón de repositorio: Implementación y carga diferida de las relaciones modelo
- 18. Elementos de carga diferida con filtrado
- 19. imágenes carga diferida dentro de jQuery Mobile
- 20. Spring + Hibernate Error de carga diferida
- 21. LINQ to SQL: en el procesamiento de la carga de asociaciones con carga diferida
- 22. Deshabilitar la carga diferida en Hibernate
- 23. patrón singleton en java. inicialización diferida
- 24. jQuery .get vs pregunta carga() el rendimiento
- 25. Android: ¿el patrón ViewHolder se implementa automáticamente en CursorAdapter?
- 26. UITableView con desplazamiento infite y carga diferida
- 27. patrón de trabajo de rendimiento rendimiento
- 28. La carga diferida en Rails 3.2.6
- 29. Cómo evitar el bloqueo de EDT con carga diferida JPA en las aplicaciones de escritorio Swing
- 30. Carga lenta en el objetivo C
@Elisha: por favor brinde más detalles sobre GetInts(). –
@masoud ramezani, se agregó más información sobre la clase de enumerador anidado GetInts. – Elisha
Gracias por su respuesta completa. –