产量突破; - 疯狂的行为

发布于 2024-08-05 05:27:02 字数 629 浏览 9 评论 0原文

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main (string[] args)
        {
            var test1 = Test1(1, 2);
            var test2 = Test2(3, 4);
        }

        static IEnumerable Test1(int v1, int v2)
        {
            yield break;
        }

        static IEnumerable Test2 (int v1, int v2)
        {
            return new String[] { };
        }
    }
}

“test1”似乎是一个 IEnumerable,其中 v1 和 v2(参数)作为字段,并且“Test1”未被调用。

“Test2”适用于“设计”:)

发生了什么事?

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main (string[] args)
        {
            var test1 = Test1(1, 2);
            var test2 = Test2(3, 4);
        }

        static IEnumerable Test1(int v1, int v2)
        {
            yield break;
        }

        static IEnumerable Test2 (int v1, int v2)
        {
            return new String[] { };
        }
    }
}

"test1" seems to be an IEnumerable with v1 and v2 (params) as fields and "Test1" is NOT called.

"Test2" works a "designed" :)

whats going on?

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

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

发布评论

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

评论(2

花开柳相依 2024-08-12 05:27:03

Test1 被调用,但除非您迭代结果,否则您不会在 yield break 上遇到断点。

基本上,Test1 被转换为一个状态机,它为您实现 IEnumerable...但是您的方法的所有主体都在该状态机内,除非您通过调用 GetEnumerator() 然后调用 MoveNext() (或使用 foreach 循环)来使用状态机,您将不会看到你的身体执行。

请参阅我的一般迭代器文章和我的一般迭代器文章。 com/Articles/Chapter6/IteratorBlockImplementation.aspx" rel="nofollow noreferrer">迭代器实现文章了解更多信息,以及 Eric Lippert 的两篇博客文章:心理调试第一部分心灵调试第二部分

Test1 is called, but unless you iterate through the result, you won't hit a breakpoint on yield break.

Basically Test1 is transformed into a state machine which implements IEnumerable for you... but all of the body of your method is inside that state machine, and unless you use the state machine by calling GetEnumerator() and then MoveNext() (or using a foreach loop) you won't see your body execute.

See my general iterator article and my iterator implementation article for more information, and also two of Eric Lippert's blog posts: Psychic Debugging part one and Psychic Debugging part two.

旧夏天 2024-08-12 05:27:03

既然您提到了 Python,我将指出 Python 中的生成器的工作方式与 C# 中的生成器非常相似。只是存在一个小小的区别,即仅使用 yield break 就可以将 C# 方法转换为生成器,而 Python 中的 raise StopIteration 则不能。

>>> def f():
...     print "Beginning of generator"
...     if False: yield
...     print "End of generator"
... 
>>> it = f()
>>> it
<generator object at 0x94fae2c>
>>> it.next()
Beginning of generator
End of generator
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Since you mentioned Python, I'm going to point out that generators in Python work quite similarly to generators in C#. There's just the small difference that yield break alone can transform a C# method into a generator, while the Python equivalent of raise StopIteration won't.

>>> def f():
...     print "Beginning of generator"
...     if False: yield
...     print "End of generator"
... 
>>> it = f()
>>> it
<generator object at 0x94fae2c>
>>> it.next()
Beginning of generator
End of generator
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文