Dan*_*ker 16
您可能听说过数组和容器 - 存储其他对象列表的对象.
但是为了使对象表示列表,它实际上不必"存储"列表.它所要做的就是为您提供允许您获取列表项的方法或属性.
在.NET框架中,接口IEnumerable是一个对象必须支持在这个意义上被视为"列表".
为了简化它(省略一些历史包袱):
public interface IEnumerable<T>
{
IEnumerator<T> GetEnumerator();
}
Run Code Online (Sandbox Code Playgroud)
所以你可以从中获得一个枚举器.该界面(再次,略微简化以消除分散注意力的噪音):
public interface IEnumerator<T>
{
bool MoveNext();
T Current { get; }
}
Run Code Online (Sandbox Code Playgroud)
因此,要遍历列表,您可以这样做:
var e = list.GetEnumerator();
while (e.MoveNext())
{
var item = e.Current;
// blah
}
Run Code Online (Sandbox Code Playgroud)
foreach
关键字可以整齐地捕获此模式:
foreach (var item in list)
// blah
Run Code Online (Sandbox Code Playgroud)
但是如何创建一种新的列表呢?是的,我们可以使用List<T>
并填充物品.但是,如果我们想要在需要时"动态"发现这些物品呢?这有一个优点,即客户端可以在前三项之后放弃迭代,并且它们不必"支付生成整个列表的成本".
手动实现这种懒惰列表会很麻烦.我们必须编写两个类,一个用于通过实现来表示列表,另一个用于通过实现IEnumerable<T>
来表示活动的枚举操作IEnumerator<T>
.
迭代器方法为我们做了所有艰苦的工作.我们写道:
IEnumerable<int> GetNumbers(int stop)
{
for (int n = 0; n < stop; n++)
yield return n;
}
Run Code Online (Sandbox Code Playgroud)
编译器将此转换为两个类.调用该方法等同于构造表示该列表的类的对象.
Mar*_*age 12
迭代器是一种抽象,它将集合中的位置概念与集合本身分离.迭代器是一个单独的对象,存储必要的状态以定位集合中的项目并移动到集合中的下一个项目.我已经看到集合在集合中保持该状态(即当前位置),但通常最好将该状态移动到外部对象.除此之外,它还允许您使用多个迭代器迭代相同的集合.
简单示例:生成整数序列的函数:
static IEnumerable<int> GetSequence(int fromValue, int toValue)
{
if (toValue >= fromValue)
{
for (int i = fromValue; i <= toValue; i++)
{
yield return i;
}
}
else
{
for (int i = fromValue; i >= toValue; i--)
{
yield return i;
}
}
}
Run Code Online (Sandbox Code Playgroud)
要在没有迭代器的情况下执行此操作,您需要创建一个数组然后枚举它...