在类中包含对列表枚举器的引用似乎改变了它的行为.匿名类的示例:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这打印"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; }
}
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?
我测试了它,对我来说它也不适用于你的具体课程.
其原因是,List<T>.Enumerator是一个可变的 struct和an.E是一个属性.
编译器为每个自动属性生成一个支持字段,如下所示:
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; }
}
Run Code Online (Sandbox Code Playgroud)
A struct是值类型,因此每次访问时an.E都会获得该值的副本.
当您打电话MoveNext()或Current,您在该副本上调用它时,此副本会发生变异.
下次访问时an.E,MoveNext()或者Current您获得了尚未迭代的枚举器的新副本.
而an.E.Current为0,而不是1因为-再-你会得到一个新的枚举MoveNext()尚未呼吁.
如果要存储列表枚举器的引用,可以Foo使用类型的属性声明类IEnumerator<int>:
public class Foo
{
public IEnumerator<int> E { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如果现在分配E = list.GetEnumerator();,枚举器将被装箱并存储引用而不是值.
| 归档时间: |
|
| 查看次数: |
62 次 |
| 最近记录: |