将列表枚举器的引用包装在类中似乎会改变其行为。匿名类的示例:
public static void Main()
{
var list = new List<int>() { 1, 2, 3 };
var an = new { E = list.GetEnumerator() };
while (an.E.MoveNext())
{
Debug.Write(an.E.Current);
}
}
我希望它打印“123”,但它只打印零并且永远不会终止。具有具体类的相同示例:
public static void Main()
{
var list = new List<int>() { 1, 2, 3 };
var an = new Foo()
{
E = list.GetEnumerator()
};
while (an.E.MoveNext())
{
Debug.Write(an.E.Current);
}
}
public class Foo
{
public List<int>.Enumerator E { get; set; }
}
这是怎么回事?
我测试了它,对我来说它也不适用于您的具体课程。
原因是List<T>.Enumerator
is a mutable struct
and an.E
is a property.
编译器为每个自动属性生成一个支持字段,如下所示:
public class Foo
{
private List<int>.Enumerator _E;
public List<int>.Enumerator get_E() { return E; }
public void set_E(List<int>.Enumerator value) { E = value; }
}
A struct
是一个值类型,所以每次访问an.E
你得到一个copy那个值。
你打电话时MoveNext()
or Current
,你调用它那个副本并且这个副本已经变异了。
下次访问时an.E
打电话MoveNext()
or Current
你得到一个尚未迭代的枚举器的新副本.
And an.E.Current
is 0
代替1
因为 - 再次 - 你会得到一个新的枚举器MoveNext()
尚未被召唤。
如果你想存储一个参考您可以声明您的类的列表的枚举器Foo
具有 type 属性IEnumerator<int>
:
public class Foo
{
public IEnumerator<int> E { get; set; }
}
如果您分配E = list.GetEnumerator();
现在,枚举器被装箱并且参考代替value被储存了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)