我发现一篇很棒的文章说明了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
但是一个基本问题是:如何在ListEnumerator中访问_objects
?
所以我想我需要在区域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()
需要实现。那么我们该怎么做,有人可以修改代码以使其正常工作吗?
答案 0 :(得分:2)
您所引用的文章代码有问题。
_objects
是类List
的私有成员,因此即使在List
的内部类中也无法在类外部访问它。
即使您公开_objects
,也必须创建List
类的对象才能访问它。
也无法修改IEnumerable
接口。
我建议采用以下两种方法。
方法1
更改ListEnumerator
类构造函数以接受List
类的对象
private class ListEnumerator : IEnumerator
{
private List _list;
public ListEnumerator(List list)
{
this._list = list;
}
private int _currentIndex = -1;
public bool MoveNext()
{
_currentIndex++;
return (_currentIndex < this._list._objects.Length);
}
public object Current
{
get
{
try
{
return this._list._objects[_currentIndex];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
public void Reset()
{
_currentIndex = -1;
}
}
您还需要从private
类的_objects
的声明中删除List
。
并将this
传递给ListEnumerator构造函数。
public class List : IEnumerable
{
object[] _objects;
public List()
{
_objects = new object[100];
}
//Other code of List class.
public IEnumerator GetEnumerator()
{
return new ListEnumerator(this);
}
}
方法2
更改ListEnumerator
类构造函数以接受对象数组。
private class ListEnumerator : IEnumerator
{
private object[] _objects;
public ListEnumerator(object[] objects)
{
this._objects = objects;
}
private int _currentIndex = -1;
public bool MoveNext()
{
_currentIndex++;
return (_currentIndex < this._objects.Length);
}
public object Current
{
get
{
try
{
return this._objects[_currentIndex];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
public void Reset()
{
_currentIndex = -1;
}
}
并在List类中按以下方式使用它。
public IEnumerator GetEnumerator()
{
return new ListEnumerator(this._objects);
}