Proposal: allow IEnumerator on foreach loop

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • cody

    #1

    Proposal: allow IEnumerator on foreach loop

    Currently it is only legal to use types which has a method named
    GetEnumerator to be used in a foreach loop.
    This makes it impossible to use the same Enumerator after and before a
    foreach loop, because GetEnumerator always returns a new one.

    My proposal would allow the following scenario:

    You could for example the first and the last element of the list as a
    special case:

    ArrayList l = new ArrayList();
    l.Add(1);
    l.Add(2);
    l.Add(3);

    IEnumerator e = l.GetEnumerator ();

    if (e.MoveNext())
    {
    object first = e.current;
    // do something with first element
    }

    // reuse enumerator from above, note that iteration starts with second
    // element, not the first, unless we call Reset on the enumerator.
    foreach object i in e)
    {
    // do something
    }

    object last = e.Current; // current still points to last element
    // do something with the last element
  • Jon Skeet [C# MVP]

    #2
    Re: Proposal: allow IEnumerator on foreach loop

    On Aug 31, 3:51 pm, cody <deutron...@gmx .dewrote:
    Currently it is only legal to use types which has a method named
    GetEnumerator to be used in a foreach loop.
    This makes it impossible to use the same Enumerator after and before a
    foreach loop, because GetEnumerator always returns a new one.
    Rather than making a language change, why not create your own
    IEnumerable implementation which is simply given an IEnumerator which
    it always returns?

    Note that for first/last special casing, you could use my
    SmartEnumerable :


    Jon

    Comment

    • cody

      #3
      Re: Proposal: allow IEnumerator on foreach loop

      Jon Skeet [C# MVP] wrote:
      On Aug 31, 3:51 pm, cody <deutron...@gmx .dewrote:
      >Currently it is only legal to use types which has a method named
      >GetEnumerato r to be used in a foreach loop.
      >This makes it impossible to use the same Enumerator after and before a
      >foreach loop, because GetEnumerator always returns a new one.
      >
      Rather than making a language change, why not create your own
      IEnumerable implementation which is simply given an IEnumerator which
      it always returns?
      >
      Note that for first/last special casing, you could use my
      SmartEnumerable :

      >
      Jon
      Yes I've read your blog, that's what gave me the idea in the first
      place.. :)
      Your enumerable is a good idea, but brings performance penalties with it.
      One could also invent an operator which yields not the elements but the
      indices of a given collection, which also allows one to use the index
      within the foreach loop, which could also be used for determining the
      first and last element.
      Making that GetIndexEnumera tor() an extension method in C# 3 would be
      very nice. The more I thing about extension methods the more I love em.

      A foreach accepting an IEnumerator would have the advantage that you
      could reuse it to save resources (If creating enumerator is a
      performance neck e.g. a serverside database cursor has to be opened, or
      whatever). I mean, what is Reset() good for when you cannot use it,
      unless you do the loop manually, without using foreach?

      Comment

      • Jon Skeet [C# MVP]

        #4
        Re: Proposal: allow IEnumerator on foreach loop

        On Aug 31, 4:31 pm, cody <deutron...@gmx .dewrote:
        Yes I've read your blog, that's what gave me the idea in the first
        place.. :)
        :)
        Your enumerable is a good idea, but brings performance penalties with it.
        Have you got a situation where those performance penalties are
        significant?
        In the case of my suggestion of an IEnumerable which just returned the
        original IEnumerator, the performance penalty would be absolutely
        *tiny*!
        One could also invent an operator which yields not the elements but the
        indices of a given collection, which also allows one to use the index
        within the foreach loop, which could also be used for determining the
        first and last element.
        Do you mean like Enumerable.Rang e in .NET 3.5? (I'm working on a
        generic Range class as part of my book, btw.)
        Making that GetIndexEnumera tor() an extension method in C# 3 would be
        very nice. The more I thing about extension methods the more I love em.
        >
        A foreach accepting an IEnumerator would have the advantage that you
        could reuse it to save resources (If creating enumerator is a
        performance neck e.g. a serverside database cursor has to be opened, or
        whatever). I mean, what is Reset() good for when you cannot use it,
        unless you do the loop manually, without using foreach?
        If you really, really need the performance, just write the foreach
        loop manually.
        I suspect that it's *very* rare that the overhead introduced by
        something like SmartEnumerable (or the other solution suggested here)
        would be significant - definitely not common enough to be worth
        requiring a language change.

        (As for what Reset is good for - very little, IMO. It's often
        unimplemented, and was probably a mistake in hindsight.)

        Jon

        Comment

        Working...