Enumerator as an argument

Ok, start with this very simple button click method.

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"); } 

This method does nothing, because each statement gracefully passes. Everything is fine until I believe that I must introduce a method for removing redundancy

  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"); } 

Although this refactoring is simple (for me, at least). This breaks the program! In the second call to AssertNext, it seems that the enumerator has already been reset to the starting point and cause an assertion error.

I can’t understand what will happen. I really feel new to this riddle.

What am I missing here?

+4
source share
2 answers

I assume this has something to do with List.Enumerator being a structure. You pass it to a method, manipulate it, and then return. Manipulation probably did not happen for your original instance.

+5
source

List<T>.Enumerator is a value type that means it copied to the local area of ​​your method, changed, and then destroyed when you exit the method. Try also passing it by reference.

+3
source

Source: https://habr.com/ru/post/1400688/


All Articles