简体   繁体   English

C#Itreator最佳方法

[英]C# Itreator best approach

Apart from (IEnumerable Returns GetEnumerator() ,for "foreach" IEnumerble is essential) 除了(IEnumerable返回GetEnumerator(),对于“ foreach”而言,IEnumerble是必不可少的)

almost the following two approaches allow us to iterate over the collection.What is 几乎以下两种方法使我们可以迭代集合。

the advantage of one over another ? 一个人比另一个人的优势? (I am not asking the difference between IEnumerable and IEnumerator). (我不是在问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);
}

approach 1 方法1

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

 {
     T[] some = vals;

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

approach 2 方法2

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

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

如果我错了,请指正我,但唯一的区别是IEnumerable和IEnumerator之间的区别,并且由于您明确地说您不是在问区别,所以两者都是很好的...

The main difference is that most API support an imput of IEnumerable<T> but not of IEnumerator<T> . 主要的区别是,大多数API支持的开关输入IEnumerable<T>但不是IEnumerator<T>

You also have to remember to call Reset() when using it while the syntax is more evident in IEnumerable<T> (Just call GetEnumerator again). 您还必须记住在使用它时会调用Reset(),而IEnumerable<T>的语法更加明显(只需再次调用GetEnumerator )。 Also see the comment of Eric Lipper about reset being a bad idea; 另请参阅Eric Lipper的有关重置不是一个好主意的评论。 if Reset isn't implemented in your IEnumerator<T> or is buggy it become a one-time-only enumerator (pretty useless in a lot of cases). 如果在您的IEnumerator<T>未实现Reset或有错误,则它将成为一次性的枚举器(在很多情况下,它几乎没有用)。

Another difference may be that you could have an IEnumerable<T> that could be enumerated from multiple threads at the same time but an IEnumerator<T> store one position in the enumerated data (Imagine a RandomEnumerable or RangeEnumerable ). 另一个区别可能是您可能有一个IEnumerable<T>可以同时从多个线程枚举,但是IEnumerator<T>在枚举数据中存储一个位置(想象一下RandomEnumerableRangeEnumerable )。

So the conclusion is that IEnumerable<T> is more versatile, but anyway if you have a function returning an IEnumerator<T> generating the IEnumerable<T> around it is simple. 因此得出的结论是IEnumerable<T>更具通用性,但是无论如何,如果您有一个返回IEnumerator<T>的函数,则在它周围生成IEnumerable<T>很简单。

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();
    }
}

Just for API consistency using IEnumerable<T> seem the best solution to me. 仅出于API一致性,使用IEnumerable<T>似乎是我的最佳解决方案。

But the issue with Reset() in IEnumerator<T> make it an unusable solution anyway, so IEnumerable<T> is the way to go. 但是IEnumerator<T> Reset()问题仍然使它成为无法使用的解决方案,因此IEnumerable<T>是解决之道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM