如何实现IEnumerator<;T>;
本文关键字:lt gt IEnumerator 何实现 实现 | 更新日期: 2023-09-27 18:26:47
此代码未进行编译,并引发以下错误:
类型"TestesInterfaces.MyCollection"已包含"Current"的定义
但是,当我删除这个模棱两可的方法时,它会不断出现其他错误。
有人能帮忙吗?
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);
}
}
}
}
我想你误解了IEnumerator<T>
。通常,集合实现IEnumerable<T>
,而不是IEnumerator<T>
。你可以这样想:
- 当一个类实现
IEnumerable<T>
时,它表示"我是一个可以枚举的东西的集合。" - 当一个类实现
IEnumerator<T>
时,它表示"我是一个枚举某个事物的事物。"
集合很少实现IEnumerator<T>
(而且可能是错误的)。通过这样做,您将集合限制为单个枚举。如果您试图在已经循环通过集合的代码段内循环通过集合,或者如果您试图同时在多个线程上循环通过集合时,您将无法执行此操作,因为集合本身存储枚举操作的状态。通常,集合(实现IEnumerable<T>
)返回一个单独的对象(实现IEnumerator<T>
),并且该单独的对象负责存储枚举操作的状态。因此,您可以有任意数量的并发或嵌套枚举,因为每个枚举操作都由一个不同的对象表示。
此外,为了使foreach
语句工作,in
关键字后面的对象必须实现IEnumerable
或IEnumerable<T>
。如果对象仅实现IEnumerator
或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();
}
}
您需要定义当前正在实现的接口。
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
我认为从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);
}