学习集合和 IEnumerable 和 IEnumerator 接口(interface)。
我有以下程序。当我走进

IEnumerator<string> name = sample.GetEnumerator();

它调用 Console.WriteLine("inside getenumerator");
class Program
    {
        static void Main(string[] args)
        {
            SampleStrings sample = new SampleStrings();
            IEnumerator<string> name = sample.GetEnumerator();
            foreach (var item in sample)
            {
                Console.WriteLine(item);
            }
            Console.ReadLine();
        }
    }
    class SampleStrings : IEnumerable<string>
    {
        public IEnumerator<string> GetEnumerator()
        {
            Console.WriteLine("inside getenumerator");

            return null;//for testing purpose only
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }

现在,如果我在使用相同的 IEnumerator<string> name = sample.GetEnumerator(); 时将 GetEnumerator 替换为如下所示
被调用然后它不会进入函数。我希望它进入函数但不返回任何东西,因为我还没有调用 movenext()
当我指定 yield 使其行为如此时会发生什么。该程序有效。
public IEnumerator<string> GetEnumerator()
        {
            Console.WriteLine("inside getenumerator");
            yield return "First";
            yield return "Second";

        }

最佳答案

包含 IEnumeratoryield 的代码被转换成两部分。

创建了一个新的 IEnumerator 类,其中包含您的原始代码,尽管进行了重写以使其按预期执行。这是您的原始代码(包括 Console.WriteLine)所在的位置。
GetEnumerator() 方法包含全新的生成代码,它简单地实例化上面定义的 IEnumerator 并返回它。

因此,在调用第一个 MoveNext() 之前,您的任何代码都不会运行。

这就是为什么您经常会看到以下模式,例如立即执行参数验证。实现分为两部分:一个普通方法和一个包含 yield 的方法。

public IEnumerator<int> GetEnumerator(string whatever)
{
  // Perform validation immediately when called
  if (whatever == null) throw new ArgumentException();
  return GetEnumeratorInternal(whatever);
}

private IEnumerator<int> GetEnumeratorInternal(string whatever)
{
  // Everything in this method happens on first MoveNext
  yield return 1;
  yield return 2;
}

关于c# - 使用 yield return 时 GetEnumerator() 方法会发生什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17990783/

10-09 22:47