返回公共 IEnumerator GetEnumerator() 的类型
本文关键字:类型 GetEnumerator IEnumerator 返回 | 更新日期: 2023-09-27 17:57:22
要实现集合,我必须完成GeEnumerator()。但是此函数的返回类型是 IEnumerator。怎么做?例如。。
class MyList : IEnumerable, IEnumerator
{
private int[] array;
int positino = -1;
public IEnumerator GetEnumerator()
{
for(int i = 0 ; i < array.Length; ++i)
{
yield return array[i];
}
}
}
array[i] 是整数而不是 IEnumerator 类型。这个函数怎么能返回整数?
它这个函数怎么能返回整数
没有,它yield return
是一个整数。这意味着它可以被编译成一个返回IEnumerable
、IEnumerable<int>
、IEnumerator
或IEnumerator<int>
的方法,这取决于你的方法说它返回的是哪个。
yield
关键字是一种便利,它允许创建具有适当MoveNext()
、Current
和Dispose
的枚举器,如果它是可枚举的,那么也使用适当的GetEnumerator
。
查看您的方法:
public IEnumerator GetEnumerator()
{
for(int i = 0 ; i < array.Length; ++i)
{
yield return array[i];
}
}
然后这是编译的东西,尽管要真正工作,它需要更多才能实际分配一些东西给array
。
当我们编译它时,它的结果与我们编写的结果相同:
private class En : IEnumerator<object>
{
private object _current;
private int _state;
public MyList _this;
public int _index;
public bool MoveNext()
{
int state = _state;
switch(state)
{
case 0:
_state = -1;
_index = 0;
break;
case 1:
_state = -1;
if(++_index >= _this.array.Length)
return false;
break;
default:
return false;
}
_current = _this.array[_index];
_state = 1;
return true;
}
public object Current
{
get { return _current; }
}
public void Reset()
{
throw new NotSupportedException();
}
public void Dispose()
{
}
object IEnumerator.Current
{
get { return _current; }
}
public En(int state)
{
_state = state;
}
}
public IEnumerator GetEnumerator()
{
var en = new En(0);
en._this = this;
return en;
}
主要区别在于,En
及其字段的名称都不是有效的 C# 名称,但是有效的 .NET 名称,因此它不能与程序员使用的任何名称冲突。
这比它需要的要多一点。它实现了IEnumerator<object>
和IEnumerator
,但这意味着编译器可以只具有IEnumerable<T>
的逻辑,并将object
用于非泛型类型的T
,而不是具有单独的逻辑。 _state
比必要的更复杂,但如果 yield
-using 方法比单个循环更复杂,则 _state
的不同值将允许它跟踪该yield
-using 方法的哪个部分与之对应。
总而言之,它在实施IEnumerator
方面做得很好。它比手动编码一个要大一点(显然比你只使用return array.GetEnumerator();
大),但不是大很多,但相反,yield
-use 方法要短得多,通常这些方法更简单。例如,在 yield
-using 方法中有一个using
块的情况下更是如此,该块在枚举器的Dispose()
中变成了适当的清理。
使用泛型和 IEnumerable int
public class MyList : IEnumerable<int>
{
public MyList()
{
array = new [] { 1, 2, 3, 4, 5, 6, 7};
}
private int[] array;
int positino = -1;
public IEnumerator<int> GetEnumerator()
{
for(int i = 0 ; i < array.Length; ++i)
{
yield return array[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
请注意,在这种特定情况下,您可以使用数组实现"作弊"而不是真正实现GetEnumerator()
:
public class MyList : IEnumerable<int>
{
public MyList()
{
array = new[] { 1, 2, 3, 4, 5, 6, 7 };
}
private int[] array;
public IEnumerator<int> GetEnumerator()
{
return ((IEnumerable<int>)array).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}