大家好,我是C#初学者,想问一个有关迭代器的问题
下面是代码,运行结果是课程:
**********
语文
数学
外语
物理
化学爱好:
**********
上网
听歌
看电影我不明白的是,其中Main函数中有一段
foreach (string str in student)
 {
     Console.WriteLine(str);
}
这里不是应该写student.Lessons 才对吗?为什么省略了.Lessons还可以打印输出数组Lessons中的元素呢
我试着把下面的 foreach (string str in student.interests)  中的 .interests去掉,结果输出的是错误的结果
请问这是怎么回事呢?郁闷,各位前辈帮我看看啊。
 using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;namespace ConsoleApplication3
{    class CollecionSample
    {        public static void Main()
        {
            Student student = new Student();
            Console.WriteLine("课程:");
            Console.WriteLine("*".PadLeft(10, '*'));
            foreach (string str in student)
            {
                Console.WriteLine(str);
            }            Console.WriteLine();
            Console.WriteLine("爱好:");
            Console.WriteLine("*".PadLeft(10, '*'));
            foreach (string str in student.interests)
            {
                Console.WriteLine(str);
            }            Console.ReadKey();
        }
    }    public class Student
    {
        public string[] interests = new string[] { "上网", "听歌", "看电影" };
        public string[] Lessons = new string[] { "语文", "数学", "外语", "物理", "化学" };        public IEnumerator GetEnumerator()
        {
            foreach (string str in Lessons)
            {
                yield return str;
            }
        }    }}

解决方案 »

  1.   

    你可以理解,迭代器其实就是一个内部实现for循环的方法体。只是其实现方法及其实现的通用性,是其提取为迭代器。
      

  2.   

    不好意思没有看到你下面的第二个问题。你在student类里的GetEnumerator()方法返回的是一个用于支持非泛型集合的迭代。所以你如果用student做为集合去循环会出现两次课程列表。
      

  3.   

    你需要理解什么是数组Array,什么是集合IConnection,什么是IList开始.
    举个简单例子:
    数组如 string ar=new string[]{"a","b","c"}
    这是一个简单字符串数组。假设我需要提取数组中的每一个元素,我该怎么办呢? 
    所以那些天才们就想出一种方案,用C#语法表达是:
    forech(string item in ar)
    {
      MessageBox.Show(item);
    }然后你可以把forech(string item in ar)这种语法理解为迭代器.专业解释:
    1.迭代器是可以返回相同类型值的有序序列的一段代码; 
      2.迭代器可用作方法、运算符或get访问器的代码体; 
      3.迭代器代码使用yield return语句依次返回每个元素,yield break将终止迭代; 
      4.可以在类中实现多个迭代器,每个迭代器都必须像任何类成员一样有惟一的名称,并且可以在foreach语句中被客户端代码调用; 
      5.迭代器的返回类型必须为IEnumerable和IEnumerator中的任意一种;
      6.迭代器是产生值的有序序列的一个语句块,不同于有一个 或多个yield语句存在的常规语句块; 
      7.迭代器不是一种成员,它只是实现函数成员的方式,理解这一点是很重要的,一个通过迭代器实现的成员,可以被其他可能或不可能通过迭代器实现的成员覆盖和重载; 
      8.迭代器块在C#语法中不是独特的元素,它们在几个方面受到限制,并且主要作用在函数成员声明的语义上,它们在语法上只是语句块而已;
    迭代器是 C# 2.0 中的新功能。迭代器是方法、get 访问器或运算符,它使您能够在类或结构中支持 foreach 迭代,而不必实现整个 IEnumerable 接口。您只需提供一个迭代器,即可遍历类中的数据结构。当编译器检测到迭代器时,它将自动生成 IEnumerable 或 IEnumerable<T> 接口的 Current、MoveNext 和 Dispose 方法。 迭代器概述
    迭代器是可以返回相同类型的值的有序序列的一段代码。迭代器可用作方法、运算符或 get 访问器的代码体。迭代器代码使用 yield return 语句依次返回每个元素。yield break 将终止迭代。有关更多信息,请参见 yield。可以在类中实现多个迭代器。每个迭代器都必须像任何类成员一样有唯一的名称,并且可以在 foreach 语句中被客户端代码调用,如下所示:foreach(int x in SampleClass.Iterator2){}迭代器的返回类型必须为 IEnumerable、IEnumerator、IEnumerable<T> 或 IEnumerator<T>。yield 关键字用于指定返回的值。到达 yield return 语句时,会保存当前位置。下次调用迭代器时将从此位置重新开始执行。迭代器对集合类特别有用,它提供一种简单的方法来迭代不常用的数据结构(如二进制树)。
      

  4.   

    foreach和for 看起来是一样的你可以这么记,
      

  5.   

    foreach (string str in student)
     {
      Console.WriteLine(str);
    }
    和 foreach (string str in student.Lessons)
     {
      Console.WriteLine(str);
    }运行效果是一样的,这是为什么呢
      

  6.   

    student 是Student类的一个实例对象
    怎么可以遍历其中的元素呢
    如错写成 student.Lessons 就是student对象中的Lessons数组
    这样写还可以理解对不起我理解能力比较差
      

  7.   

    Student里
    类里有两个public的string[]数组成员
    并且你已经在类里实现了IEnumerator GetEnumerator();
    public IEnumerator GetEnumerator()
    {
         foreach (string str in Lessons)
    }
    所以你在Main里实例化Student后,对student实例使用foreach()遍历,会调用该类型已经实现了的GetEnumerator(),其中只是迭代了Lessons成员而后面一个foreach (string str in student.interests) 实际则是对该实例的成员interests进行迭代,而它是一个string[],数组类型内部已经实现了GetEnumerator()方法)
      

  8.   

    原来如此,我把GetEnumerator()里的Lessons改成了interests 结果显示成兴趣了非常感谢7L的朋友 也感谢大家的帮助!