c# - 我什么时候应该在 C# 中使用 IEnumerator 进行循环?

标签 c# iterator ienumerable loops

我想知道是否有任何时候使用 IEnumerator 而不是 foreach 循环来迭代集合?例如,是否有任何时候使用以下代码示例中的任何一个比另一个更好?

IEnumerator<MyClass> classesEnum = myClasses.GetEnumerator();
while(classesEnum.MoveNext())
    Console.WriteLine(classesEnum.Current);

代替

foreach (var class in myClasses)
    Console.WriteLine(class);

最佳答案

首先,请注意您的示例(foreachGetEnumerator 之间)的一大区别是 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/

相关文章:

c# - 迭代器和枚举器的区别

C#/Java | AES256加密/解密

c# - 不要逃避换行

c# - 如何仅使用一个 Controller 动态检索表?

c# - 在枚举选择中返回索引

c# - 如何在 IEnumerable 对象中执行 foreach

c# - 在不遇到集合修改异常的情况下从列表中删除项目的最有效方法?

c# - 是否值得为调用其他方法的方法编写测试,这些方法 100% 被单个单元测试覆盖?

java - 如何在java中迭代Set并向其中添加元素?

rust - 在flat_map中返回不同种类的迭代器