CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Oct 2006
    Posts
    181

    Enhancing Looping With Enumerators

    Before using enumerators I would have have an exposed data structures and loops like this:

    Code:
    ' Exposed data structures
    Public Blocks As New SortedList(Of Integer, Block)
    Public RedBlocks As New SortedList(Of Integer, Block)
    Public BlueBlocks As New SortedList(Of Integer, Block)
    
    ' Loops
    For Each blockKVP As KeyValuePair(Of Integer, Block) In Blocks
        Dim block As Block = blockKVP.Value
        ...
    Next
    
    For Each blockKVP As KeyValuePair(Of Integer, Block) In BlueBlocks
        Dim block As Block = blockKVP.Value
        ...
    Next
    Whenever code added/removed blocks to the list the code had to make sure to add/remove from each list. This of course is error prone. Also, if I wanted to maintain another list of blocks in a different color I'd have to modify each block of code that added/removed from the lists.

    So I created enumerator classes to encapsulate all this and to protect the data structures. It also made the loop syntax simpler and easier to read.

    Code:
    ' Enumerators
    Public Class BlockEnumerator
        Implements IEnumerator(Of Block)
       ...
    End Class
    Public Class RedBlockEnumator
        Implements IEnumerator(Of Block)
        ....
    End Class
    Public Class BlockList
        Implements IEnumerable(Of Block)
        ...
    End Class
    Public Class RedBlockList
        Implements IEnumerable(Of Block)
        ...
    End Class
    
    ' Protected data structures
    Private _Blocks As New SortedList(of integer, Block)
    Public Blocks As New BlockList(_Blocks)
    Public RedBlocks As New BlockList(_Blocks)
    
    ' Simple loops
    For Each block In Blocks
        ...
    Next
    For Each block In RedBlocks
        ...
    Next
    Now my question. I would like to only have one public list and to select the subset of blocks in the looping syntax. I have few thoughts what the syntax might be but I don't know what class/data structures I need in order to do this.

    Code Examples
    Code:
    ' Protected data structures
    Private _Blocks As New SortedList(of integer, Block)
    Public Blocks As New BlockList(_Blocks)
    
    ' Loops through all blocks
    For Each block In Blocks
        ...
    Next
    For Each block In Blocks.AllBlocks
        ...
    Next
    For Each block In Blocks(BlockColor.AllColors)
        ...
    Next
    ' Loops through red blocks
    For Each block In Blocks.RedBlocks
        ...
    Next
    For Each block In Blocks(BlockColor.RedBlocks)
        ...
    Next
    Well, does anyone have any suggestions or know if this is even possible?


    Thanks,
    Last edited by Scott.Macmaster; December 10th, 2008 at 04:45 PM.

  2. #2
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Enhancing Looping With Enumerators

    I would create a SINGLE class that hadd "All" the blocks, then expose enumerators that only returned the ones which met the requirements.

    NO multiple collections to maintain, smaller, faster, less error prone, easier to use....whats not to like?
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  3. #3
    Join Date
    Mar 2007
    Location
    Argentina
    Posts
    579

    Re: Enhancing Looping With Enumerators

    Quote Originally Posted by Scott.Macmaster View Post
    Before using enumerators I would have have an exposed data structures and loops like this:

    Code:
    ' Loops
    For Each blockKVP As KeyValuePair(Of Integer, Block) In Blocks
        Dim block As Block = blockKVP.Value
        ...
    Next
    Whenever code added/removed blocks to the list the code had to make sure to add/remove from each list. This of course is error prone. Also, if I wanted to maintain another list of blocks in a different color I'd have to modify each block of code that added/removed from the lists.
    try:
    Code:
    ' Loops
    For Each blockKVP As KeyValuePair(Of Integer, Block) In Blocks.Clone
        Dim block As Block = blockKVP.Value
        ...
    Next
    That way, yo would iterate on each object on the original SortedList, at the cost of duplicating your data structure before the For...Next. You can delete the same objects in the KeyValuePair, without ruining the logic under you For..Each...Next
    Last edited by Marraco; December 11th, 2008 at 07:02 AM.
    [Vb.NET 2008 (ex Express)]

  4. #4
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Enhancing Looping With Enumerators

    Clonig the list usually has a bigger performance hit than just using a good pattern for handling addition/deletion. This can be implemented at the collection class level. It is also much easier to make thread safe by localizing all of the locking.
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  5. #5
    Join Date
    Oct 2006
    Posts
    181

    Re: Enhancing Looping With Enumerators

    Well, that's what I want to do, have everything in one class. I did some more thinking and found a solution. For some reason it didn't initial occur to me I could have a function in an enumerable class that returns an object of a different enumerable class.

    This'll work perfectly for my block example. However, the project I'm actually working on involves the list ordered in different ways so I'll still need to manage multiple lists. However, it'll all be in one class and the enumerable objects returned by the functions in the primary enumerable object won't have add/remove functions so my data structures will be completely protected.

    Code:
    ' Enumerators
    Public Class BlocksByIdEnumerator
       Implements IEnumerator(Of Block)
       ...
    End Class
    Public Class BlocksByNameEnumerator
       Implements IEnumerator(Of Student)
       ...
    End Class
    
    ' Enumerable classes
    Public Class BlocksList
       Implements IEnumerable(Of Block)
    
       Private Blocks As New SortedList(of Integer, Block)
       Private BlocksByName As New SortedList(of String, Block)
       
       Public Functions ByName() As BlocksByNameList
          Return New BlocksByNameList(BlocksByName)
       End Function
       ...
    End Class
    Public Class BlocksByNameList
       Implements IEnumerable(Of Block)
       
       Private Blocks As SortedList(Of String, Block)
       ...
    End Class
    
    ' Fully protected data structure
    Public blocks As BlocksList
    
    ' Looping through blocks
    For Each block In blocks
       ...
    Next
    ' Loop through blocks in a different order
    For Each block In blocks.ByName
       ...
    Next
    Well, I don't think this can be improved anymore.


    Thanks,

  6. #6
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Enhancing Looping With Enumerators

    Scott, since you posted abbriviated code, I can not be 100% certain, but it still looks as if there is a postential for error.

    1) Create BlockList
    2) Get Local Reference to BlockList.ByName
    3) Remove item from Local Reference (of type BlocksByNameList)

    Will the original BlockList properly reflect the change?

    Also what happens if the caller tries "new BlocksByNameList" directly?

    It seems that this implementation does NOT optimally meet the goal of "Make classes as DIFFICULT as possible to use INCORRECTLY" - Scott Meyers....
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  7. #7
    Join Date
    Oct 2006
    Posts
    181

    Re: Enhancing Looping With Enumerators

    I had said, "and the enumerable objects returned by the functions in the primary enumerable object won't have add/remove functions so my data structures will be completely protected"

    Without a add/remove functions you can't modify the internal data structure with the local reference returned by BlockList.ByName.

    I only have one constructor for BlocksByNameList

    Code:
    Public Sub New(blocksByName As SortedList(As String, Block))
       Blocks = blocksByName
    End Sub
    So you can't initialize a BlocksByName object manually with the sortedlist inside of Blocks since there isn't a way to get a reference to it. Not that it would matter since it doesn't have add/remove functions. You could initialize it with your own sortedlist but since it doesn't have add/remove functions that would be pointless.

    If you have thoughts on how my code could by misused I'd like to know.


    Thanks,

  8. #8
    Join Date
    Jan 2006
    Location
    Fox Lake, IL
    Posts
    15,007

    Re: Enhancing Looping With Enumerators

    Post it all. Attach it as a file if it is too big to paste.
    David

    CodeGuru Article: Bound Controls are Evil-VB6
    2013 Samples: MS CODE Samples

    CodeGuru Reviewer
    2006 Dell CSP
    2006, 2007 & 2008 MVP Visual Basic
    If your question has been answered satisfactorily, and it has been helpful, then, please, Rate this Post!

  9. #9
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Enhancing Looping With Enumerators

    Quote Originally Posted by Scott.Macmaster View Post
    I If you have thoughts on how my code could by misused I'd like to know.
    I confess that I was looking much more ad the code, than the text. It seems you have most of the major bases covered, with the possible of some unnecessary object lifetime (this could only be confirmed with a fully compilable piece of code that could be carefully analyzed with a proper profiler.
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured