为什么Enumerator
在同一功能中不能跟踪项目,而MoveNext
在其他功能中发生操作,为什么不能跟踪项目?
例:
public static void Test()
{
var array = new List<Int32>(new Int32[] { 1, 2, 3, 4, 5 });
var e = array.GetEnumerator();
e.MoveNext();
e.MoveNext();
Console.WriteLine(e.Current); // 2
Incremenet(e);
Console.WriteLine(e.Current); //2
}
static void Incremenet(IEnumerator<Int32> e)
{
Console.WriteLine("Inside " + e.Current); //2
e.MoveNext();
Console.WriteLine("Inside " + e.Current); // 3
e.MoveNext();
Console.WriteLine("Inside " + e.Current); //4
}
我原本希望在最后的CW中获得5,但我却获得2,因为它从未增加。为什么在函数返回时忘记了函数MoveNext
内部Increment
?
干杯。
List<T>
的枚举类型List<T>.Enumerator
不是a class
,而是a struct
。由于GetEnumerator
公开了返回类型为List<T>.Enumerator
,当您使用时var
,其e
类型为List<T>.Enumerator
,因此当您将其传递给时Incremenet
,它会自动装箱成为一个IEnumerator<Int32>
对象。这是您看到的奇怪行为的原因。
如果您输入e
as IEnumerator<Int32>
,则在您获得对象后立即进行装箱,因此不会发生这种奇怪的行为:无论您在其中运行其他代码Test
还是在其中运行其他代码,其作用都相同Increment
(我固定了该方法的拼写方式,它不是“ Incremenet”)。
public static void Test()
{
var array = new List<Int32> { 1, 2, 3, 4, 5 };
IEnumerator<Int32> e = array.GetEnumerator(); // boxed here
e.MoveNext();
e.MoveNext();
Console.WriteLine(e.Current); // 2
Increment(e);
Console.WriteLine(e.Current); // now it's 4
}
static void Increment(IEnumerator<Int32> e)
{
Console.WriteLine("Inside " + e.Current); // 2
e.MoveNext();
Console.WriteLine("Inside " + e.Current); // 3
e.MoveNext();
Console.WriteLine("Inside " + e.Current); // 4
}
它以其类型公开,而不是IEnumerator<T>
出于性能原因。在这种情况下foreach
非常聪明,可以调用MoveNext
并且Current
无需装箱或虚拟派遣,并且可以毫无问题地处理值类型语义。如您所见,当您不十分注意如何处理它时,确实会造成混乱,因为可变struct
的是邪恶的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句