2

This code is not compiling, and it's throwing the following error:

The type 'TestesInterfaces.MyCollection' already contains a definition for 'Current'

But when I delete the ambiguous method, it keeps giving other errors.

Can anyone help?

public class MyCollection<T> : IEnumerator<T>
{
    private T[] vector = new T[1000];
    private int actualIndex;

    public void Add(T elemento)
    {
        this.vector[vector.Length] = elemento;
    }

    public bool MoveNext()
    {
        actualIndex++;
        return (vector.Length > actualIndex);
    }

    public void Reset()
    {
        actualIndex = -1;
    }

    void IDisposable.Dispose() { }

    public Object Current
    {
        get
        {
            return Current;
        }
    }


    public T Current
    {
        get
        {
            try
            {
                T element = vector[actualIndex];
                return element;
            }
            catch (IndexOutOfRangeException e)
            {
                throw new InvalidOperationException(e.Message);
            }
        }
    }
}
4

3 回答 3

12

我想你是误会了IEnumerator<T>。通常,集合实现IEnumerable<T>,而不是IEnumerator<T>。你可以这样想它们:

  • 当一个类实现IEnumerable<T>时,它表明“我是可以枚举的事物的集合”。
  • 当一个类实现IEnumerator<T>时,它是在声明“我是一个枚举某物的东西”。

集合实现的情况很少(而且可能是错误的)IEnumerator<T>。通过这样做,您将集合限制为单个枚举。如果您尝试在已经循环通过集合的代码段中循环通过集合,或者如果您尝试同时在多个线程上循环通过集合,您将无法执行此操作,因为您的集合本身存储枚举操作的状态。通常,集合(实现IEnumerable<T>)返回一个单独的对象(实现IEnumerator<T>)并且该单独的对象负责存储枚举操作的状态。因此,您可以拥有任意数量的并发或嵌套枚举,因为每个枚举操作都由一个不同的对象表示。

此外,为了使foreach语句起作用,in关键字后面的对象必须实现IEnumerableor IEnumerable<T>IEnumerator如果对象只实现or ,它将不起作用IEnumerator<T>

我相信这是您正在寻找的代码:

public class MyCollection<T> : IEnumerable<T>
{
    private T[] vector = new T[1000];
    private int count;

    public void Add(T elemento)
    {
        this.vector[count++] = elemento;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return vector.Take(count).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
于 2013-08-07T13:46:31.577 回答
9

您需要定义当前正在实现的接口。

Object IEnumerator.Current
{
    //
}

public T Current
{
    //
}

这样,您的班级就有 2 个Current属性。但您可以同时访问它们。

MyCollection<string> col = new MyCollection<string>();
var ienumeratort = col.Current; //Uses IEnumerator<T>
var ienumerator = (IEnumerator)col.Current; //uses IEnumerator
于 2013-08-07T13:25:52.067 回答
1

我认为从 C# 2.0 开始,您有一种非常简单的方法来实现迭代器,编译器通过创建状态机在幕后做了很多繁重的工作。值得研究一下。话虽如此,在这种情况下,您的实现将如下所示:

    public class MyCollection<T>
    {
        private T[] vector = new T[1000];
        private int actualIndex;

        public void Add(T elemento)
        {
            this.vector[vector.Length] = elemento;
        }

        public IEnumerable<T> CreateEnumerable()
        {
          for (int index = 0; index < vector.Length; index++)
          {
            yield return vector[(index + actualIndex)];
          }
       }
   }

虽然我不确定actualIndex 的目的 - 但我希望你明白这一点。

在正确初始化 MyCollection 之后,从消费者的角度来看,下面的代码片段有点像:

MyCollection<int> mycoll = new MyCollection<int>();
            foreach (var num in mycoll.CreateEnumerable())
            {
                Console.WriteLine(num);
            }
于 2018-02-14T18:08:55.987 回答