Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Would you use a custom enumerator?

Would you use a custom enumerator?

Scheduled Pinned Locked Moved C#
csharpcomquestion
9 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    DaveyM69
    wrote on last edited by
    #1

    I have a bunch of different structs that implement IMyType. I also have some more advanced structs that are essentially containers for x number of IMyType instances (they are not lists). They need to be iterated so I am implementing IEnumerable<IMyType>. At the moment I have made a custom enumerator that has a params IMyType[] myTypes parameter in the contructor and using this type of code in the IEnumerable structs:

    public IEnumerator<IMyType> GetEnumerator()
    {
    return new MyTypeEnumerator(
    new IMyType[] {
    new MyType(...),
    new MyTypeOther(...) });
    }

    This works fine but I've been considering getting rid of the MyTypeEnumerator and using this instead:

    public IEnumerator<IMyType> GetEnumerator()
    {
    IEnumerable<IMyType> collection = new IMyType[] {
    new MyType(...),
    new MyTypeOther(...) };
    return collection.GetEnumerator();
    }

    Obviously both work just fine and are pretty much identical. Which would you prefer? Edit: Alternatively, I could just use return new MyTypeEnumerator(this); and let the MyTypeEnumerator take care of it. I don't like that idea - ignore

    Dave
    Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
    BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

    B R C 3 Replies Last reply
    0
    • D DaveyM69

      I have a bunch of different structs that implement IMyType. I also have some more advanced structs that are essentially containers for x number of IMyType instances (they are not lists). They need to be iterated so I am implementing IEnumerable<IMyType>. At the moment I have made a custom enumerator that has a params IMyType[] myTypes parameter in the contructor and using this type of code in the IEnumerable structs:

      public IEnumerator<IMyType> GetEnumerator()
      {
      return new MyTypeEnumerator(
      new IMyType[] {
      new MyType(...),
      new MyTypeOther(...) });
      }

      This works fine but I've been considering getting rid of the MyTypeEnumerator and using this instead:

      public IEnumerator<IMyType> GetEnumerator()
      {
      IEnumerable<IMyType> collection = new IMyType[] {
      new MyType(...),
      new MyTypeOther(...) };
      return collection.GetEnumerator();
      }

      Obviously both work just fine and are pretty much identical. Which would you prefer? Edit: Alternatively, I could just use return new MyTypeEnumerator(this); and let the MyTypeEnumerator take care of it. I don't like that idea - ignore

      Dave
      Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
      BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

      B Offline
      B Offline
      BobJanova
      wrote on last edited by
      #2

      You'd normally only create a custom enumerator if you want to be able to enumerate the (virtual) collection without holding the whole list in memory all at once. So I don't quite understand the purpose of your implementation. If you can define a list form for your object, why not just expose that?

      public IList<IMyType> Items {
      get {
      IList<IMyType> list = new List<IMyType>();
      list.Add(new MyType(...));
      list.Add(new MyTypeOther(...));
      return list;
      }
      }

      public IEnumerator<IMyType> GetEnumerator() { return Items.GetEnumerator(); }

      Actually you don't need to implement IEnumerable at all if you do that, you can put the List property on the interface and users can do foreach(IMyType item in myObject.Items) instead of foreach(IMyType item in myObject).

      D 1 Reply Last reply
      0
      • B BobJanova

        You'd normally only create a custom enumerator if you want to be able to enumerate the (virtual) collection without holding the whole list in memory all at once. So I don't quite understand the purpose of your implementation. If you can define a list form for your object, why not just expose that?

        public IList<IMyType> Items {
        get {
        IList<IMyType> list = new List<IMyType>();
        list.Add(new MyType(...));
        list.Add(new MyTypeOther(...));
        return list;
        }
        }

        public IEnumerator<IMyType> GetEnumerator() { return Items.GetEnumerator(); }

        Actually you don't need to implement IEnumerable at all if you do that, you can put the List property on the interface and users can do foreach(IMyType item in myObject.Items) instead of foreach(IMyType item in myObject).

        D Offline
        D Offline
        DaveyM69
        wrote on last edited by
        #3

        There is another class that has a method:

        public void Send(IEnumerable<IMyType> collection)
        {
        foreach(IMyType myType in collection)
        {
        // .....
        }
        }

        This is the only place the IEnumerable is used (no need for any sort of list at all), so that leaves the second method as the prefered, essentially what your list is doing but without the list.

        Dave
        Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
        BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

        B 1 Reply Last reply
        0
        • D DaveyM69

          I have a bunch of different structs that implement IMyType. I also have some more advanced structs that are essentially containers for x number of IMyType instances (they are not lists). They need to be iterated so I am implementing IEnumerable<IMyType>. At the moment I have made a custom enumerator that has a params IMyType[] myTypes parameter in the contructor and using this type of code in the IEnumerable structs:

          public IEnumerator<IMyType> GetEnumerator()
          {
          return new MyTypeEnumerator(
          new IMyType[] {
          new MyType(...),
          new MyTypeOther(...) });
          }

          This works fine but I've been considering getting rid of the MyTypeEnumerator and using this instead:

          public IEnumerator<IMyType> GetEnumerator()
          {
          IEnumerable<IMyType> collection = new IMyType[] {
          new MyType(...),
          new MyTypeOther(...) };
          return collection.GetEnumerator();
          }

          Obviously both work just fine and are pretty much identical. Which would you prefer? Edit: Alternatively, I could just use return new MyTypeEnumerator(this); and let the MyTypeEnumerator take care of it. I don't like that idea - ignore

          Dave
          Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
          BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

          R Offline
          R Offline
          Richard Deeming
          wrote on last edited by
          #4

          Another alternative to consider:

          public IEnumerator GetEnumerator()
          {
          yield return new MyType(...);
          yield return new MyTypeOther(...);
          ...
          }


          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

          D 1 Reply Last reply
          0
          • D DaveyM69

            There is another class that has a method:

            public void Send(IEnumerable<IMyType> collection)
            {
            foreach(IMyType myType in collection)
            {
            // .....
            }
            }

            This is the only place the IEnumerable is used (no need for any sort of list at all), so that leaves the second method as the prefered, essentially what your list is doing but without the list.

            Dave
            Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
            BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

            B Offline
            B Offline
            BobJanova
            wrote on last edited by
            #5

            But the point is you are creating the list anyway (well, an array to be precise, but it's pretty much the same thing). However, implementing only IEnumerable and not IList (or exposing a list) implies that the enumeration can be run without the whole thing being in memory all at once. It would be cleaner to expose the list and to pass that to Send (i.e. instead of calling Send(myObject), call Send(myObject.Items), to my mind.

            D 1 Reply Last reply
            0
            • R Richard Deeming

              Another alternative to consider:

              public IEnumerator GetEnumerator()
              {
              yield return new MyType(...);
              yield return new MyTypeOther(...);
              ...
              }


              "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

              D Offline
              D Offline
              DaveyM69
              wrote on last edited by
              #6

              Good thinking, much better creating the new IMyTypes as needed. 5d :-D

              Dave
              Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
              BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

              1 Reply Last reply
              0
              • D DaveyM69

                I have a bunch of different structs that implement IMyType. I also have some more advanced structs that are essentially containers for x number of IMyType instances (they are not lists). They need to be iterated so I am implementing IEnumerable<IMyType>. At the moment I have made a custom enumerator that has a params IMyType[] myTypes parameter in the contructor and using this type of code in the IEnumerable structs:

                public IEnumerator<IMyType> GetEnumerator()
                {
                return new MyTypeEnumerator(
                new IMyType[] {
                new MyType(...),
                new MyTypeOther(...) });
                }

                This works fine but I've been considering getting rid of the MyTypeEnumerator and using this instead:

                public IEnumerator<IMyType> GetEnumerator()
                {
                IEnumerable<IMyType> collection = new IMyType[] {
                new MyType(...),
                new MyTypeOther(...) };
                return collection.GetEnumerator();
                }

                Obviously both work just fine and are pretty much identical. Which would you prefer? Edit: Alternatively, I could just use return new MyTypeEnumerator(this); and let the MyTypeEnumerator take care of it. I don't like that idea - ignore

                Dave
                Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
                BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

                C Offline
                C Offline
                Clifford Nelson
                wrote on last edited by
                #7

                As was said earlier, there is not much reason to create a custom enumerator these days. The reason for an enumerator is to be able to use the ForEach loop. The Yield statement. Then there is also LINQ, Not sure why you are even bothering with an Enumerator given the alternatives avaialable.

                D 1 Reply Last reply
                0
                • C Clifford Nelson

                  As was said earlier, there is not much reason to create a custom enumerator these days. The reason for an enumerator is to be able to use the ForEach loop. The Yield statement. Then there is also LINQ, Not sure why you are even bothering with an Enumerator given the alternatives avaialable.

                  D Offline
                  D Offline
                  DaveyM69
                  wrote on last edited by
                  #8

                  Clifford Nelson wrote:

                  there is not much reason to create a custom enumerator these days

                  That's why I asked, it felt somewhat unnecessary.

                  Clifford Nelson wrote:

                  Not sure why you are even bothering with an Enumerator given the alternatives avaialable

                  There are many types in the library that are responsible for creating multiple instances of the interface IMyType (the quantity and implementation differs by the type) when required, and all these types need to be able to be passed to one common method so it can iterate over the interface instances - IEnumerable<IMyType> fits this scenario/concept perfectly, what is was designed for IMO.

                  Dave
                  Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
                  BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

                  1 Reply Last reply
                  0
                  • B BobJanova

                    But the point is you are creating the list anyway (well, an array to be precise, but it's pretty much the same thing). However, implementing only IEnumerable and not IList (or exposing a list) implies that the enumeration can be run without the whole thing being in memory all at once. It would be cleaner to expose the list and to pass that to Send (i.e. instead of calling Send(myObject), call Send(myObject.Items), to my mind.

                    D Offline
                    D Offline
                    DaveyM69
                    wrote on last edited by
                    #9

                    I see where you're coming from. Richard's solution below is the best for this particular situation I think as the array doesn't actually need to be in memory all at once. I can simply create the instances as required using yield return directly. Thanks for your input though, it has helped clarify some of my thinking in regards to iterators and foreach which will be helpful in future, and encouraged me to dig deeper into the whole thing that I previously just took for granted :thumbsup:

                    Dave
                    Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
                    BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups