题
好的,让我们从这个非常简单的按钮点击方法
private void button1_Click(object sender, EventArgs e)
{
int counter = 1;
List<int> items = new int[] { 1, 2, 3 }.ToList();
List<int>.Enumerator enm = items.GetEnumerator();
// 1
if (!enm.MoveNext())
throw new Exception("Unexpected end of list");
if (enm.Current != counter)
throw new Exception(String.Format("Expect {0} but actual {1}", counter, enm.Current));
counter++;
// 2
if (!enm.MoveNext())
throw new Exception("Unexpected end of list");
if (enm.Current != counter)
throw new Exception(String.Format("Expect {0} but actual {1}", counter, enm.Current));
counter++;
//3
if (!enm.MoveNext())
throw new Exception("Unexpected end of list");
if (enm.Current != counter)
throw new Exception(String.Format("Expect {0} but actual {1}", counter, enm.Current));
counter++;
if (enm.MoveNext())
throw new Exception("Unexpected continuation of list");
}
.
此方法没有,因为每个断言都优雅地通过。事情很好,直到我相信我应该介绍一种删除冗余的方法
static void AssertNext(ref int counter, List<int>.Enumerator e)
{
if (!e.MoveNext())
throw new Exception("Unexpected end of list");
if (e.Current != counter)
throw new Exception(String.Format("Expect {0} but actual {1}", counter, e.Current));
counter++;
}
private void button2_Click(object sender, EventArgs e)
{
var counter = 1;
var items = new int[] { 1, 2, 3 }.ToList();
var enm = items.GetEnumerator();
AssertNext(ref counter, enm);
AssertNext(ref counter, enm);
AssertNext(ref counter, enm);
if (enm.MoveNext()) throw new Exception("Unexpected continuation of list");
}
.
即使,这种重构是简单的(至少为我,至少)。它确实打破了这个程序! 在对AssertNext的第二个调用中,似乎枚举器已重置为起点并导致断言失败。
我无法理解发生了什么。我真的觉得这个谜题的初学者。
我在这里错过了什么?
解决方案
我想象它与list.enumerator是一个结构。你将它传递给一种方法,操纵它,然后返回。操纵可能没有发生原始实例。
其他提示
List<T>.Enumerator
是一个值类型,意味着它被复制到方法的本地范围内,更改,然后在离开方法时销毁。尝试通过引用传递它。
不隶属于 StackOverflow