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.