C#IEnumerable,IEnumerator重置函数未被调用

我基本上试图让我的类能够使用foreach进行迭代.我读了这个教程. MSDN.看起来非常直截了当.但是,当我想第二次迭代时,我遇到了问题.我调试了它;事实证明它没有调用Reset()函数.

A级

class A : IEnumerable,IEnumerator
{
    int[] data = { 0,1,2,3,4 };

    int position = -1;

    public object Current
    {
        get
        {
            return data[position];
        }
    }

    public bool MoveNext()
    {
        position++;
        return (position < data.Length);
    }

    public void Reset()
    {
        position = -1;
    }

    public IEnumerator GetEnumerator()
    {
        return (IEnumerator)this;
    }
}

当我运行以下主要功能时;它永远不会调用Reset()函数.所以,经过一个循环,我再也无法迭代我的课了.

主要

static void Main(string[] args)
{
    A a = new A();

    foreach (var item in a)
    {
        Console.WriteLine(item);
    }

    Console.WriteLine("--- First foreach finished. ---");

    foreach (var item in a)
    {
        Console.WriteLine(item);
    }
}

输出

0
1
2
3
4
--- First foreach finished. ---
Press any key to continue . . .

有什么想法吗?

解决方法

每次调用foreach时,都会要求新的IEnumerator.返回你的类实例一个坏主意 – 你应该创建一个单独的类来实现IEnumerator,然后返回它.

这通常通过使用嵌套(私有)类并返回它的实例来完成.您可以将类A实例传递给私有类(使其可以访问数据),并将位置字段放在该类中.它将允许同时创建多个枚举器,并且可以与后续的foreach调用一起正常工作.

例如,要修改代码,您可以执行以下操作:

using System;
using System.Collections;

class A : IEnumerable
{
    int[] data = { 0,4 };

    public IEnumerator GetEnumerator()
    {
        return new AEnumerator(this);
    }

    private class AEnumerator : IEnumerator
    {
        public AEnumerator(A inst)
        {
            this.instance = inst;
        }

        private A instance;
        private int position = -1;

        public object Current
        {
            get
            {
                return instance.data[position];
            }
        }

        public bool MoveNext()
        {
            position++;
            return (position < instance.data.Length);
        }

        public void Reset()
        {
            position = -1;
        }

    }
}

请注意,您也可以直接返回数组的枚举器(虽然我假设您正在尝试学习如何创建干净的枚举器):

class A : IEnumerable
{
    int[] data = { 0,4 };

    public IEnumerator GetEnumerator()
    {
        return data.GetEnumerator();
    }
}

最后,您可以使用iterators以更简单的方式实现此功能

class A : IEnumerable
{
    int[] data = { 0,4 };

    public IEnumerator GetEnumerator()
    {
        for (int i=0;i<data.Length;++i)
           yield return data[i];
    }
}

话虽这么说,我强烈建议实现IEnumerable< int>除了IEnumerable.仿制药在使用方面做得更好.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...