我想知道是否有任何时候使用 IEnumerator 而不是 foreach 循环来迭代集合?例如,是否有任何时候使用以下代码示例中的任何一个比另一个更好?
IEnumerator<MyClass> classesEnum = myClasses.GetEnumerator();
while(classesEnum.MoveNext())
Console.WriteLine(classesEnum.Current);
代替
foreach (var class in myClasses)
Console.WriteLine(class);
最佳答案
首先,请注意您的示例(foreach
和 GetEnumerator
之间)的一大区别是 foreach
保证调用 Dispose ()
在迭代器上,如果迭代器是 IDisposable
。这对许多迭代器很重要(例如,它们可能会消耗外部数据馈送)。
实际上,在某些情况下 foreach
并没有我们希望的那么有用。
首先,讨论了“第一项”案例here (foreach / detecting first iteration) .
但更多;如果您尝试编写缺少的 Zip
方法来将两个可枚举序列拼接在一起(或 SequenceEqual
方法),您会发现您无法使用 foreach
在两个序列上,因为这将执行交叉连接。您需要为其中之一直接使用迭代器:
static IEnumerable<T> Zip<T>(this IEnumerable<T> left,
IEnumerable<T> right)
{
using (var iter = right.GetEnumerator())
{
// consume everything in the first sequence
foreach (var item in left)
{
yield return item;
// and add an item from the second sequnce each time (if we can)
if (iter.MoveNext())
{
yield return iter.Current;
}
}
// any remaining items in the second sequence
while (iter.MoveNext())
{
yield return iter.Current;
}
}
}
static bool SequenceEqual<T>(this IEnumerable<T> left,
IEnumerable<T> right)
{
var comparer = EqualityComparer<T>.Default;
using (var iter = right.GetEnumerator())
{
foreach (var item in left)
{
if (!iter.MoveNext()) return false; // first is longer
if (!comparer.Equals(item, iter.Current))
return false; // item different
}
if (iter.MoveNext()) return false; // second is longer
}
return true; // same length, all equal
}
关于c# - 我什么时候应该在 C# 中使用 IEnumerator 进行循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/456433/