Enumerator behavior changes based on how we reference it?

前端 未结 1 471
北海茫月
北海茫月 2021-01-19 11:55

Wrapping a reference to the list\'s enumerator inside a class seems to change its behavior. Example with an anonymous class:

public static void Main()
{
            


        
1条回答
  •  粉色の甜心
    2021-01-19 12:24

    I tested it and for me it does not work with your concrete class either.

    The reason is that List.Enumerator is a mutable struct and an.E is a property.

    The compiler generates a backing field for each auto-property like this:

    public class Foo
    {
        private List.Enumerator _E;
        public List.Enumerator get_E() { return E; }
        public void set_E(List.Enumerator value) { E = value; }
    }
    

    A struct is a value-type, so every-time you access an.E you get a copy of that value.

    When you call MoveNext() or Current, you call it on that copy and this copy is mutated.

    The next time you access an.E to call MoveNext() or Current you get a fresh copy of the not-yet-iterated enumerator.

    And an.E.Current is 0 instead of 1 because - again - you get a fresh enumerator that MoveNext() was not yet called upon.


    If you want to store a reference of the list's enumerator you could declare your class Foo with a property of type IEnumerator:

    public class Foo
    {
        public IEnumerator E { get; set; }
    }
    

    If you assign E = list.GetEnumerator(); now, the enumerator gets boxed and a reference instead of a value is stored.

    0 讨论(0)
提交回复
热议问题