Question

Okay, let's 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 do nothing because every assertion gracefully pass. Things are fine until I believe I should introduce a method to remove 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");
    }

Even though, this refactoring is straightforward (for me, at least). It does break the program ! On the second call to AssertNext, it seems like the enumerator was already reset to the starting point and cause the assertion to fail.

I cannot understand what happen. I really feel like a beginner with this puzzle.

What I miss here ?

Was it helpful?

Solution

I'm imagining it has something to do with List.Enumerator being a struct. You're passing it to a method, manipulating it, and then returning. The manipulation will probably not have happened for your original instance.

OTHER TIPS

List<T>.Enumerator is a value type meaning that it's copied into the local scope of your method, altered, and then destroyed upon leaving the method. Try passing it by reference too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top