如何产量实现延迟加载的格局? [英] How yield implements the pattern of lazy loading?
问题描述
如何收益率
实施延迟加载的方式
?
推荐答案
,直到需要它的产量实现不达到code。
yield implementation doesn't reach the code until it's needed.
例如,该code:
public IEnumerable<int> GetInts()
{
yield return 1;
yield return 2;
yield return 3;
}
将和 实际上编译成一个实现嵌套类 Will actually compile into a nested class which implements 使用反射,你可以看到: Using reflector you can see:
修改 - 增加更多的信息关于 Edit - adding more info about 当枚举被要求为当前对象它返回被连接到当前状态的对象。 When the enumerator is asked for the current object it returns the object which is connected to the current state. 为了表明code只计算在需要时,你可以看看这个例子: In order to show that the code is evaluated only when it's required you can look at this example:
我希望它更清楚一点。我建议看看在code与反射,并观察编译code为你改变收益code。 I hope it's a bit more clear. I recommend to take a look at the code with Reflector and observe the compiled code as you change the "yield" code. 这篇关于如何产量实现延迟加载的格局?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! GetInts身体();
的IEnumerable&LT; INT&GT返回类的一个实例。
IEnumerable<int>
and the body of GetInts()
will return an instance of that class.public IEnumerable<int> GetInts()
{
<GetInts>d__6d d__d = new <GetInts>d__6d(-2);
d__d.<>4__this = this;
return d__d;
}
GetInts
实施:
这种实现使得偷懒的方法是根据枚举
的 的MoveNext()
方法。当产生枚举嵌套类(&LT; GetInts&GT; d__6d
中的例子),它有一个状态,每个状态的值连接(这是一个简单的例子,在更先进的情况下的价值进行评估时,code达到的状态)。如果我们采取一看的MoveNext()
$ C $的C &LT; GetInts&GT; d__6d
我们拭目以待状态:GetInts
implementation:
The way this implementation makes it lazy is based on the Enumerator
MoveNext()
method. When the enumerable nested class is generated (<GetInts>d__6d
in the example), it has a state and to each state a value is connected (this is a simple case, in more advanced cases the value will be evaluated when the code reach the state). If we take a look in the MoveNext()
code of <GetInts>d__6d
we'll see the state: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));
}
}