Manually increment an enumerator inside foreach loop

前端 未结 8 1051
情话喂你
情话喂你 2021-01-18 06:20

I have a nested while loop inside a foreach loop where I would like to advance the enumerator indefinitately while a certain condition is met. To do this I try casting the e

相关标签:
8条回答
  • 2021-01-18 07:09

    One alternative not yet mentioned is to have an enumerator return a wrapper object which allows access to itself in addition to the data element being enumerated. For sample:

    struct ControllableEnumeratorItem<T>
    {
      private ControllableEnumerator parent;
      public T Value {get {return parent.Value;}}
      public bool MoveNext() {return parent.MoveNext();}
      public ControllableEnumeratorItem(ControllableEnumerator newParent)
        {parent = newParent;}
    }
    

    This approach could also be used by data structures that want to allow collections to be modified in controlled fashion during enumeration (e.g. by including "DeleteCurrentItem", "AddBeforeCurrentItem", and "AddAfterCurrentItem" methods).

    0 讨论(0)
  • 2021-01-18 07:16

    Many of the other answers recommend using continue, which may very well help you do what you need to do. However, in the interests of showing manually moving the enumerator, first you must have the enumerator, and that means writing your loop as a while.

    using (var enumerator = times.GetEnumerator())
    {
        DateTime time;
        while (enumerator.MoveNext()) 
        {
            time = enumerator.Current;
            // pre-condition code
            while (condition)
            {
                if (enumerator.MoveNext())
                {
                    time = enumerator.Current;
                    // condition code
                }
                else 
                {
                    condition = false;
                }
            }
            // post-condition code
        }
    }
    

    From your comments:

    How can the foreach loop advance it if it doesn't implement the IEnumerator interface?

    In your loop, time is a DateTime. It is not the object that needs to implement an interface or pattern to work in the loop. times is a sequence of DateTime values, it is the one that must implement the enumerable pattern. This is generally fulfilled by implementing the IEnumerable<T> and IEnumerable interfaces, which simply require T GetEnumerator() and object GetEnumerator() methods. The methods return an object implementing IEnumerator<T> and IEnumerator, which define a bool MoveNext() method and a T or object Current property. But time cannot be cast to IEnumerator, because it is no such thing, and neither is the times sequence.

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