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

在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] =

我发现了一篇关于IEnumerable和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;
       }
    }
}
并将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);
}