除了(IEnumerable返回GetEnumerator(),对于<!>“; foreach <!>”; IEnumerble是必不可少的)

几乎以下两种方法允许我们迭代集合。什么是

一个人的优势是什么? (我不是在问IEnumerable之间的区别 和IEnumerator)。

static void Main()
{
    IEnumerator<int> em = MyEnumerator<int>(new int[] { 1, 2, 3, 4 });
    IEnumerator<int> e = Collection<int>
                        (new int[] { 1, 2, 3, 4 }).GetEnumerator();

    while (em.MoveNext())
    {
        Console.WriteLine(em.Current);
    }

    while (e.MoveNext())
    {
        Console.WriteLine(e.Current);
    }
    Console.ReadKey(true);
}

接近1

 public static IEnumerator<T> MyEnumerator<T>(T[] vals )

 {
     T[] some = vals;

     foreach (var v in some)
     {
       yield return v;
     }
}

接近2

public static IEnumerable<T> Collection<T>(T[] vals)
     {
         T[] some = vals;

         foreach (var v in some)
         {
             yield return v;
         }
     }
有帮助吗?

解决方案

主要区别在于大多数API支持IEnumerable<T>但不支持IEnumerator<T>

您还必须记住在使用时调用Reset(),而语法在GetEnumerator中更明显(只需再次调用RandomEnumerable)。另请参阅Eric Lipper关于重置是一个坏主意的评论;如果您的RangeEnumerable中没有实现重置,或者它是错误的,它将成为一次性的枚举器(在很多情况下都很无用)。

另一个区别可能是您可以同时从多个线程枚举Reset(),但<=>在枚举数据中存储一个位置(想象一下<=>或<=>)。

所以结论是<=>更通用,但无论如何,如果你有一个返回<=>生成<=>的函数的函数很简单。

class EnumeratorWrapper<T> : IEnumerable<T>
{
    Func<IEnumerator<T>> m_generator;
    public EnumeratorWrapper(Func<IEnumerator<T>> generator)
    {
        m_generator = generator;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return m_generator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return m_generator();
    }
}

仅使用<=>的API一致性似乎是我的最佳解决方案。

但<=>中<=>的问题无论如何都会使它成为无法使用的解决方案,所以<=>是可行的方法。

其他提示

如果我错了,请纠正我,但唯一的区别是IEnumerable和IEnumerator之间的区别,因为你明确表示你不是要求区别,两者都是好的......

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top