Hi I have had a problem with some method that should perform action on some IEnumerator object instance, the code sample shows the case:
class Program
{
static void Main(string[] args)
{
string[] testArray = { "Item1", "Item2" };
var query = testArray.Select((item, index) => new { index, item });
Console.WriteLine("Query run 1, {0}", Environment.NewLine);
foreach (var obj in query)
{
Console.WriteLine("{0}", obj);
}
Console.WriteLine("Query run 2, {0}", Environment.NewLine);
doAction<object>(query as IEnumerator<object>, obj => Console.WriteLine(obj) );
Console.WriteLine("Query run 3 ( same as run 1), {0}", Environment.NewLine);
foreach (var obj in query)
{
Console.WriteLine("{0}", obj);
}
Object tmp = Console.ReadLine();
}
private static void doAction<T>(IEnumerator<T> enumerator, Action<T> action)
{
if (enumerator == null)
{
throw new ArgumentNullException("enumerator");
}
if (action == null)
{
throw new ArgumentNullException("action");
}
while (enumerator.MoveNext())
{
action(enumerator.Current);
}
}
}
The output:
Query run 1,
{ index = 0, item = Item1 }
{ index = 1, item = Item2 }
Query run2,
Query run 3 ( same as run 1),
{ index = 0, item = Item1 }
{ index = 1, item = Item2 }
Does anyone know what method doAction do not take action ?
The real problem is that i need the answer in English language, because my is really bad and i can not explain why this is happening to my mate.
Thanks in advance.
Thnaks.
Yes – you shouldn’t be using
IEnumerator<T>directly, onlyIEnumerable<T>. Basically you’re seeing an oddity of the way that the C# compiler implements iterator blocks: there’s one type which implements bothIEnumerable<T>andIEnumerator<T>. That’s unusual in itself, but is done for performance reasons. It’s not something you should take advantage of or rely on.Fundamentally, casting an
IEnumerable<T>toIEnumerator<T>is a bad idea – you shouldn’t do it. They’re different interfaces representing subtly different ideas – the difference between “a sequence which can be iterated over” and “something which is iterating over a sequence”.If you really want to use
IEnumerator<T>as the parameter type fordoAction(which would normally beDoAction, btw) just callGetEnumerator()instead: