yield
如何实施lazy loading
的模式?yield如何实现延迟加载的模式?
回答
收益实现直到需要时才会到达代码。
例如,下面的代码:
public IEnumerable<int> GetInts()
{
yield return 1;
yield return 2;
yield return 3;
}
将实际编译成执行IEnumerable<int>
和GetInts()
身体会返回一个类的实例嵌套类。
使用反射镜可以看到:
public IEnumerable<int> GetInts()
{
<GetInts>d__6d d__d = new <GetInts>d__6d(-2);
d__d.<>4__this = this;
return d__d;
}
编辑 - 增加更多的信息关于GetInts
实现:
此实现使得懒惰是基于Enumerator
MoveNext()
方法的方式。生成可枚举的嵌套类(示例中的<GetInts>d__6d
)时,它具有一个状态,并且每个状态都连接一个值(这是一个简单的例子,在更高级的情况下,代码到达状态时将评估该值)。如果我们采取的<GetInts>d__6d
的MoveNext()
代码一看,我们会看到状态:
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;
}
当枚举被要求为当前对象返回连接到当前状态的对象。
为了表明,只有当它需要你可以看看下面这个例子的代码进行评估:
[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));
}
}
我希望这是更清晰一点。我建议使用Reflector来查看代码,并在更改“yield”代码时观察编译的代码。
如果您想了解更多关于什么编译器使用yield return
这样做的时候,检查这篇文章乔恩斯基特:Iterator block implementation details
Briljant重定向,实际上。 +1 – peSHIr 2010-05-03 10:20:03
基本上迭代器使用yield
语句implementated被编译成一个实现state machine类。
如果您从不foreach
(=迭代并实际使用)返回的IEnumerable<T>
,代码永远不会实际执行。如果你这样做,只需要确定下一个返回值所需的最小代码就可以执行,只有当请求下一个值时才能恢复执行。
当您在调试器中单步执行此类代码时,您实际上可以看到此行为发生。至少尝试一次:我认为这是一步一步发生的。
- 1. 如何实现延迟加载文本
- 2. 延迟加载实现的问题
- 3. 加载弹出模式的延迟
- 4. 模式的延迟加载与Python
- 5. 隐式延迟加载vs显式延迟加载
- 6. 存储库模式:模型关系的实现和延迟加载
- 7. 在VBScript中实现延迟加载的模块
- 8. 对实体延迟加载
- 9. 如何实现容器类的延迟加载?
- 10. 如何在UITableView中实现类似UIImageView的延迟加载
- 11. 如何实现延迟加载的属性
- 12. 如何在角4.3.1中实现嵌套的延迟加载?
- 13. 延迟加载组织模式
- 14. 延迟加载延迟
- 15. 如何以RESTful方式“延迟加载”?
- 16. 延迟加载模型
- 17. 如何延迟加载?
- 18. 如何使用Spring数据JPA(JPARepository)实现延迟加载?
- 19. 如何使用RequireJS实现延迟加载?
- 20. 如何使用SQLite实现延迟加载?
- 21. 如何在Vaadin中实现延迟加载树?
- 22. 如何使用PostSharp实现延迟加载?
- 23. 如何在Tapestry中实现延迟区域重新加载?
- 24. 如何在GridView中实现延迟加载图像
- 25. 如何在Angular中实现延迟加载动态img src
- 26. 如何实现延迟加载到uiscroll视图
- 27. 如何使用jQuery延迟对象实现预加载程序
- 28. 如何在elixir中实现延迟模式?
- 29. 实体框架延迟加载和DTO模式
- 30. 延迟加载
@Elisha:请提供关于GetInts()的更多详细信息。 – 2010-05-03 10:53:54
@masoud ramezani,增加了关于GetInts嵌套枚举类的更多信息。 – Elisha 2010-05-03 13:52:38
谢谢你的完整答案。 – 2010-05-03 14:22:36