马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#技术求助 ASP.NET技术求助

【源码下载】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接外包项目】 面试-葵花宝典下载

官方一群:

官方二群:

C#迭代器讲解,什么是迭代器

[复制链接]
查看3654 | 回复0 | 2015-1-9 09:47:06 | 显示全部楼层 |阅读模式
 迭代器模式是行为模式的一种范例,行为模式是一种简化对象之间通信的一种设计模式。在.NET中使用IEnumerator和IEnumerable接口及它们的泛型等价物来封装的,如果一个类型实现了IEnumerable接口,就说明它是可迭代的,调用GetEnumerator方法返回IEnumerator的实现,这是迭代器本身。

  C#1使用foreach语句实现了访问迭代器的内置支持,foreach语句会被编译成使用GetEnumerator和MoveNext方法以及Current属性。C#中迭代器只能向后访问,而C++中迭代器可以支持前后访问。

  背景,假设有一个关于学生的队列,每个学生依次报出自己的名字,

    Student类如下:

[C#] 纯文本查看 复制代码
class Student
{
    public string Name { get; set; }

    public Student(string name)
    {
        Name = name;
    }

    public void SayName()
    {
        Console.WriteLine(Name);
    }
}


有一个实现IEnumerable的Queue的泛型类,如下

[C#] 纯文本查看 复制代码
class Queue<T> : IEnumerable<T> where T : class
{
    public List<T> objects = new List<T>();

    public Queue(List<T> list)
    {
        objects = list;
    }

    //实现从IEnumerable中的GetEnumerator方法
    /*
        个人觉得这个方法在迭代中只会调用一次,不然每次都返回一个新的QueueIterator<T>对象,位置记录都会重置为-1
    */
    public IEnumerator<T> GetEnumerator()
    {
        return new QueueIterator<T>(this);  
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}



 使用GetEnumerator方法返回一个迭代器,而迭代器需要实现IEnumerator接口,如下

[C#] 纯文本查看 复制代码
class QueueIterator<T> : IEnumerator<T> where T : class
{
    private ConsoleDemo.Chapter6.Queue<T> q = null;

    int startPoint = -1;    //用于保存游标的位置

    public QueueIterator(ConsoleDemo.Chapter6.Queue<T> q)
    {
        this.q = q;
    }

    //返回合适位置上的T类型实例,这个例子中调用提这个自动属性
    public T Current
    {
        get
        {
            if (startPoint==-1 || startPoint==q.objects.Count)
            {
                throw new InvalidOperationException();
            }
            int index = startPoint + q.objects.Count;
            index = index % q.objects.Count;
            return q.objects[index];
        }
    }

    object IEnumerator.Current
    {
        get
        {
            if (startPoint == -1 || startPoint == q.objects.Count)
            {
                throw new InvalidOperationException();
            }
            int index = startPoint + q.objects.Count;
            index = index % q.objects.Count;
            return q.objects[index];
        }
    }

    public void Dispose()
    {
        
    }

    public bool MoveNext()
    {
        if (startPoint != q.objects.Count)
        {
            startPoint++;
        }
        return startPoint < q.objects.Count;
    }
    //当迭代结束后,会调用这个方法,则下一次迭代后重新从第一个位置开始
    public void Reset()
    {
        startPoint = -1;
    }
}



分别要去实现从IEnumerator中的Current属性、Dispose方法(有必要的话)、MoveNext方法、Reset方法。

C#论坛 www.ibcibc.com IBC编程社区
C#
C#论坛
IBC编程社区
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则