在C#中实现自己的集合但需要修改IEnumerable?
Implement own collection in C# but need to modify the 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
但一个基本问题是:如何在 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()
需要实现。那么我们如何才能做到这一点,任何人都可以修改代码以使其工作吗?
您引用的文章代码有问题。
_objects
是 class List
的私有成员,因此无法在 class 之外访问它,即使是来自 class 的内部成员List
.
即使你制作了_objects
public,不创建List
class.
的对象也无法访问
也没有办法IEnumerable
界面可以修改
我建议采用以下两种方法。
方法一
更改 ListEnumerator
class 构造函数以接受 List
class
的对象
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;
}
}
您还需要从 List
class 中 _objects
的声明中删除 private
。
并将 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);
}
}
方法二
更改 ListEnumerator
class 构造函数以接受对象数组。
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;
}
}
并在列表 class.
中使用如下
public IEnumerator GetEnumerator()
{
return new ListEnumerator(this._objects);
}
我找到了一篇很好的文章来说明 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
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()
需要实现。那么我们如何才能做到这一点,任何人都可以修改代码以使其工作吗?
您引用的文章代码有问题。
_objects
是 class List
的私有成员,因此无法在 class 之外访问它,即使是来自 class 的内部成员List
.
即使你制作了_objects
public,不创建List
class.
也没有办法IEnumerable
界面可以修改
我建议采用以下两种方法。
方法一
更改 ListEnumerator
class 构造函数以接受 List
class
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;
}
}
您还需要从 List
class 中 _objects
的声明中删除 private
。
并将 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);
}
}
方法二
更改 ListEnumerator
class 构造函数以接受对象数组。
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;
}
}
并在列表 class.
中使用如下public IEnumerator GetEnumerator()
{
return new ListEnumerator(this._objects);
}