如何在c#的foreach循环中调用GetEnumerator方法?



我正在使用迭代器模式,当我在示例代码

中发现逻辑时,我感到有点困惑
class MonthCollection : IEnumerable
        {
          public string[] months = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
            public IEnumerator GetEnumerator()
            {
                // Generates values from the collection
                foreach (string element in months)
                    yield return element;
            }
        }
        static void Main()
        {
            MonthCollection collection = new MonthCollection();
            // Consumes values generated from collection's GetEnumerator method
            foreach (string n in collection)
                Console.Write(n + " ");
            Console.WriteLine("n");
        }

在这段代码中,访问数组到字符串的正常方式是在foreach语句

中像这样调用month_variable

MonthCollection collection = new MonthCollection();
foreach (string n in collection.months){}

但是我不明白foreach是如何访问的集合,甚至不直接调用months变量

MonthCollection collection = new MonthCollection();
foreach (string n in collection){}

更新1

我不明白的是,在上面的类

中,如果不像这样调用变量months,我怎么能访问它呢?
static void Main()
        {
            MonthCollection collection = new MonthCollection();
            // Consumes values generated from collection's GetEnumerator method
            foreach (string n in collection.months)
                Console.Write(n + " ");
            Console.WriteLine("n");
        }

而不是像这样

 MonthCollection collection = new MonthCollection();
               method
                foreach (string n in collection)
                    Console.Write(n + " ");
                Console.WriteLine("n");

foreach循环不需要集合,它所需要的是一个具有GetEnumerator()方法返回IEnumerator的对象,在您的情况下,IEnumerable实现。

c#编译器生成剩余的"魔力"——一个引用枚举对象的隐藏临时变量,开始枚举的代码,获取每个项的代码,以及查看枚举何时结束的代码。

在你的例子中,c#依赖于你的实现来获得months数组的内容,使用另一个"魔法"——yield return结构。这个构造允许您实现GetEnumerator(),而无需为其编写单独的类。该构造被转换为带有状态机的类,允许您从循环中间"返回"对象,然后在从迭代器请求下一项时重新启动到原来的位置。

yield return返回的对象不一定来自一个集合。您甚至可以将集合中的对象与其他对象混合使用,例如

public IEnumerator GetEnumerator() {
    // Generates values from the collection
    foreach (string element in months) {
        yield return element + " will start soon!";
        yield return element;
        yield return element + " has ended.";
    }
}

foreach循环间接访问变量months,通过代码实现GetEnumerator()

最新更新