简体   繁体   中英

C# Itreator best approach

Apart from (IEnumerable Returns GetEnumerator() ,for "foreach" IEnumerble is essential)

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).

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

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

 {
     T[] some = vals;

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

approach 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> .

You also have to remember to call Reset() when using it while the syntax is more evident in IEnumerable<T> (Just call GetEnumerator again). Also see the comment of Eric Lipper about reset being a bad idea; 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).

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 ).

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.

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.

But the issue with Reset() in IEnumerator<T> make it an unusable solution anyway, so IEnumerable<T> is the way to go.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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