【问题标题】:yield break; - crazy behaviour产量中断; - 疯狂的行为
【发布时间】:2010-12-01 02:19:00
【问题描述】:
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”的作品是“设计的”:)

怎么了?

【问题讨论】:

    标签: c# .net yield break


    【解决方案1】:

    Test1 调用了,但除非你遍历结果,否则你不会在yield break上遇到断点。

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

    有关更多信息,请参阅我的 general iterator articleiterator implementation 文章,以及 Eric Lippert 的两篇博文:Psychic Debugging part onePsychic Debugging part two

    【讨论】:

      【解决方案2】:

      既然您提到了 Python,我将指出 Python 中的生成器的工作方式与 C# 中的生成器非常相似。只是 yield break 单独可以将 C# 方法转换为生成器,而 raise StopIteration 的 Python 等效项不会。

      >>> 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-21
        • 1970-01-01
        • 1970-01-01
        • 2011-04-14
        • 2014-08-21
        相关资源
        最近更新 更多