在C#中实现自己的集合,但需要修改IEnumerable吗?
我发现了一篇关于IEnumerable和IEnumerator的好文章 以下是源代码:在C#中实现自己的集合,但需要修改IEnumerable吗?,c#,interface,ienumerable,C#,Interface,Ienumerable,我发现了一篇关于IEnumerable和IEnumerator的好文章 以下是源代码: public class List : IEnumerable { private object[] _objects; public List() { _objects = new object[100]; } public void Add(object obj) { _objects[_objects.Count] =
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;
}
}
}
并将ListNumerator修改为:
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
只有一个方法需要实现。那么我们该怎么做呢?有人能修改代码使其正常工作吗?您所指的文章的代码有问题
\u objects
是类列表
的私有成员,因此不能在类之外访问它,即使是从列表
的内部类访问它
即使将\u对象
设置为公共对象,如果不创建列表
类的对象,也无法访问该对象
此外,无法修改IEnumerable
接口
我建议采取以下两种方法
方法1
更改列表分子
类构造函数以接受列表
类的对象
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;
}
}
方法2
更改ListNumerator类构造函数以接受对象数组
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;
}
}
你的问题不够清楚,你说的“让它工作”是什么意思?什么不起作用?您还可以粘贴使用自定义集合的方式吗?如果您将
ListEnumerator
的构造函数更改为接受对象数组,然后像使用newlistenumerator(this.\u objects)一样使用它会怎么样
?@LeiYang问题是,要让它工作,你需要在IEnumerable接口中有更多的方法,但它只有一个方法。谢谢@ChetanRanpariya,从来没有意识到嵌套类不能访问周围类的私有成员。我有这个顾虑,因为你为什么相信链接的文章是正确的(您已经看到编译错误,例如Count
),如果我需要一些自定义集合,为什么不先找到msdn文章?那么请解释一下你是否有一些特殊要求。在我发布这个问题之前,我实际上也在考虑方法2。最后一个问题,是否意味着每个集合。数组、ArrayList、List都有嵌套的私有类(用于实现IEnumerator)在源代码中?(这个问题实际上是不正确的,因为只有数组需要实现IEnumerator,其他集合实际上包含数组对象,它可以通过调用arrayObject.GetEnumerator()获得IEnumerator);
你说得对……如果所有集合类都可以使用Array.GetEnumerator()的话,它们不需要特定的枚举器实现。但我不确定Microsoft是如何做到的。假设每个集合都使用数组作为内部集合来存储数据也是安全的。您可以查看Microsoft代码。我的意思是,假设每个集合都使用数组作为内部集合来存储数据也是不安全的。这需要特定的实现用于不同集合的IEnumerator。
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;
}
}
public class List : IEnumerable
{
object[] _objects;
public List()
{
_objects = new object[100];
}
//Other code of List class.
public IEnumerator GetEnumerator()
{
return new ListEnumerator(this);
}
}
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;
}
}
public IEnumerator GetEnumerator()
{
return new ListEnumerator(this._objects);
}