猿问

在 C# 中实现自己的集合但需要修改 IEnumerable?

我发现一篇很棒的文章说明了 IEnumerable 和 IEnumerator


https://programmingwithmosh.com/csharp/ienumerable-and-ienumerator/


以下是源代码:


public class List : IEnumerable

{

    private object[] _objects;


    public List()

    {

        _objects = new object[100];

    }


    public void Add(object obj)

    {

        _objects[_objects.Count] = obj;

    }


    public IEnumerator GetEnumerator()

    {

        return new ListEnumerator();     //region 1

    } 


    private class ListEnumerator : IEnumerator 

    {

       private int _currentIndex = -1;

       public bool MoveNext()

       {

          _currentIndex++;

           return (_currentIndex < _objects.Count); 

       }

       public object Current

       {

         ...

       }

       public void Reset()

       {

           _currentIndex = -1;

       }

    }

}

我在这篇文章中发现了一些错误,可能是一些拼写错误,例如_objects.Count应该是_objects.Length ,但一个基本问题是:如何_objects在 ListEnumerator 中获得访问权限?所以我想我需要在区域 1 中传递 'this'


 public IEnumerator GetEnumerator()

 {

    return new ListEnumerator(this);

 } 

并将 ListEnumerator 修改为:


private class ListEnumerator : IEnumerator 

{

   private int _currentIndex = -1;

   IEnumerable aggregate = null;

   public ListEnumerator(IEnumerable param)

   {

      aggregate  = param

   }


   public bool MoveNext()

   {

      _currentIndex++; 

      return (_currentIndex < aggregate.Count);   //important region

   }

   public object Current

   {

      //don't worry about the boundary check/exceptions

     get

     {

         return aggregate[_currentIndex];  //important region

     }

   }

...

}

为了做到这一点, IEnumerable 也需要像


interface IEnumerable 

{

   IEnumerator GetEnumerator();

   int Count{get;}

   object this[int itemIndex]{set;get;}

}

但我们都知道IEnumerable只有一种方法GetEnumerator()需要实现。那么我们该如何做到这一点,任何人都可以修改代码以使其工作吗?


噜噜哒
浏览 99回答 1
1回答

繁花如伊

您所引用的文章的代码有问题。_objects是类的私有成员,List因此不能在类外部访问它,即使是从List.即使您_objects公开,如果不创建类对象也无法访问它List。也没有办法IEnumerable修改界面。我建议遵循两种方法。方法一更改ListEnumerator类构造函数以接受List类的对象private class ListEnumerator : IEnumerator&nbsp;{&nbsp; &nbsp; private List _list;&nbsp; &nbsp; public ListEnumerator(List list)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; this._list = list;&nbsp; &nbsp; }&nbsp; &nbsp; private int _currentIndex = -1;&nbsp;&nbsp; &nbsp; public bool MoveNext()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _currentIndex++;&nbsp; &nbsp; &nbsp; &nbsp; return (_currentIndex < this._list._objects.Length);&nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; public object Current&nbsp; &nbsp; {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; get&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this._list._objects[_currentIndex];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch (IndexOutOfRangeException)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new InvalidOperationException();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public void Reset()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _currentIndex = -1;&nbsp; &nbsp; }}您还需要从in classprivate的声明中删除。并传递给 ListEnumerator 构造函数。_objectsListthispublic class List : IEnumerable{&nbsp; &nbsp; object[] _objects;&nbsp; &nbsp; public List()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _objects = new object[100];&nbsp; &nbsp; }&nbsp; &nbsp; //Other code of List class.&nbsp; &nbsp; public IEnumerator GetEnumerator()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp;return new ListEnumerator(this);&nbsp; &nbsp; }}方法二更改ListEnumerator类构造函数以接受对象数组。private class ListEnumerator : IEnumerator&nbsp;{&nbsp; &nbsp; private object[] _objects;&nbsp; &nbsp; public ListEnumerator(object[] objects)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; this._objects = objects;&nbsp; &nbsp; }&nbsp; &nbsp; private int _currentIndex = -1;&nbsp;&nbsp; &nbsp; public bool MoveNext()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _currentIndex++;&nbsp; &nbsp; &nbsp; &nbsp; return (_currentIndex < this._objects.Length);&nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; public object Current&nbsp; &nbsp; {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; get&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this._objects[_currentIndex];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch (IndexOutOfRangeException)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new InvalidOperationException();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public void Reset()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _currentIndex = -1;&nbsp; &nbsp; }}并在 List 类中使用它。public IEnumerator GetEnumerator(){&nbsp; &nbsp;return new ListEnumerator(this._objects);}&nbsp;
随时随地看视频慕课网APP
我要回答