文章目录
- 1. 枚举
 - 1.1 枚举结构梳理
 - 1.2 枚举完整代码
 - 1.3 枚举知识点补充
 
- 2. 迭代两种命名空间接口
 - 3. yield语句
 
1. 枚举
1.1 枚举结构梳理
  结构图
 
   上图内容可能依旧不通俗易懂,这里使用最简明的话语告诉大家实现方式.
- foreach语句就是集合的遍历操作,我们如果想要完成一个集合的遍历操作我们需要做哪些操作呢?毫无疑问的,我们首先需要拥有元素的读取操作,还需要一个数据的滚动操作(读取下一个元素)。这两个通用的方法读取操作我们设置为Current属性,滚动操作设置为MoveNext方法,这些东西全部都被我们封装到IEnumerator接口当中,我们通过实现这个接口完成相应的操作
 
public class Data : IEnumerator{
    public int[] data = {1, 2, 3, 4, 5};
    int position = -1;
    object IEnumerator.Current{
        get{
            return data[position];
        }
    }
    
    public bool MoveNext(){
        position++;
        return (position < 5);
    }
    public void Reset(){
        position = -1;
    }
}
 
- 最核心的步骤IEnumerator接口完成了,现在我们需要关心的就是如何在类当中让我们可以找到这个接口,这个时候我们其实只需要实现一个名为GetEnumerator()的方法即可,这个方法需要返回实现IEnumerator接口的实现类即可
 
public class GetDate{
    public IEnumerator GetEnumerator(){
        return new Data();
    }
}
 
- 最后就可以使用了,foreach先去类里面找GetEnumerator()方法,通过这个方法拿到IEnumerator接口的实现类,再通过这个实现类内部定义的操作对数据进行遍历,这个就是foreach关键字的调用原理
 
static void Main(){
    GetDate getDate = new GetDate();
    foreach(int x in getDate){
        Console.WriteLine(x);
    }
}
 
1.2 枚举完整代码
using System;
using System.Collections;
public class Data : IEnumerator
{
    public int[] data = {1, 2, 3, 4, 5};
    int position = -1;
    object IEnumerator.Current{
        get{
            return data[position];
        }
    }
    public bool MoveNext(){
        position++;
        return (position < 5);
    }
    public void Reset(){
        position = -1;
    }
}
public class GetDate{
    public IEnumerator GetEnumerator(){
        return new Data();
    }
}
class App{
    static void Main(){
        GetDate getDate = new GetDate();
        foreach(int x in getDate){
            Console.WriteLine(x); // 输出: 1 2 3 4 5
        }
    }
}
 
1.3 枚举知识点补充
- 通过上述步骤我们其实已经大概了解了foreach的内部调用原理了,但是对于手写的GetEnumerator方法我们推出了一个新的接口IEnumerable去包装它,其实它的本质也就是代替了我们在方法当中手写GetEnumerator,也是一个很好的纠错提示,这样子可以更好的防止我们自己手写方法名字错误
 
public class GetDate : IEnumerable{ // 和我们上述步骤的方法没有太大区别,也就是加入一个接口的实现
    public IEnumerator GetEnumerator(){
        return new Data();
    }
}
 
2. 迭代两种命名空间接口
- 非泛型命名空间:System.Collection
 
- 泛型命名空间:System.Collection.Generic.IEnumerator
 

























