Linq 结果有问题

发布于 2024-11-10 07:18:02 字数 1770 浏览 1 评论 0原文

您好,我遇到了一些应该对某些 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 不采取操作?

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

提前致谢。

谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

听风吹 2024-11-17 07:18:03

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

从根本上来说,将 IEnumerable 转换为 IEnumerator 是一个坏主意 - 您不应该这样做。它们是不同的接口,代表着微妙不同的想法——“可以​​迭代的序列”和“正在序列上迭代的东西”之间的区别。

如果您确实想要使用 IEnumerator 作为 doAction 的参数类型(通常是 DoAction ,顺便说一句)只需调用 GetEnumerator() 即可:

using (var iterator = query.GetEnumerator())
{
    doAction<object>(iterator, obj => Console.WriteLine(obj) );
}

Yes - you shouldn't be using IEnumerator<T> directly, only IEnumerable<T>. Basically you're seeing an oddity of the way that the C# compiler implements iterator blocks: there's one type which implements both IEnumerable<T> and IEnumerator<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> to IEnumerator<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 for doAction (which would normally be DoAction, btw) just call GetEnumerator() instead:

using (var iterator = query.GetEnumerator())
{
    doAction<object>(iterator, obj => Console.WriteLine(obj) );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文