Linq结果出现问题

时间:2011-05-27 18:13:52

标签: c# linq ienumerable

嗨我遇到了一些应该对某些IEnumerator对象实例执行操作的方法有问题,代码示例显示了这种情况:

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

        }
    }

输出:

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 }

有谁知道doAction哪种方法不采取行动?

真正的问题是我需要英语答案,因为我真的很糟糕,我无法解释为什么这会发生在我的伴侣身上。

提前致谢。

Thnaks。

1 个答案:

答案 0 :(得分:3)

是的 - 您不应该直接使用IEnumerator<T>,而只能使用IEnumerable<T>。基本上你看到C#编译器实现迭代器块的方式很奇怪:有一种类型实现了IEnumerable<T> IEnumerator<T>。这本身并不常见,但是出于性能原因。这不是你应该利用或依赖的东西。

从根本上说,将IEnumerable<T>转换为IEnumerator<T>是一个坏主意 - 你不应该这样做。它们是不同的界面,代表了截然不同的想法 - “可以迭代的序列”和“ 迭代序列的东西”之间的差异。

如果确实想要IEnumerator<T>作为doAction的参数类型(通常为DoAction,btw),请致电{{1}而不是:

GetEnumerator()