<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Joacim's view on stuff : IEnumerable, visual basic</title><link>http://msmvps.com/blogs/joacim/archive/tags/IEnumerable/visual+basic/default.aspx</link><description>Tags: IEnumerable, visual basic</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>The Untouchables (part III) – Adding iterators to our immutable stack</title><link>http://msmvps.com/blogs/joacim/archive/2009/09/07/the-untouchables-part-iii-adding-iterators-to-our-immutable-stack.aspx</link><pubDate>Mon, 07 Sep 2009 13:39:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1721381</guid><dc:creator>Joacim Andersson</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/joacim/rsscomments.aspx?PostID=1721381</wfw:commentRss><comments>http://msmvps.com/blogs/joacim/archive/2009/09/07/the-untouchables-part-iii-adding-iterators-to-our-immutable-stack.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/joacim/archive/2009/09/07/the-untouchables-part-ii-creating-an-immutable-stack-with-vb.aspx"&gt;In my last post&lt;/a&gt; I showed you a VB translation of Eric Lippert&amp;rsquo;s &lt;a target="_blank" href="http://blogs.msdn.com/ericlippert/archive/2007/12/04/immutability-in-c-part-two-a-simple-immutable-stack.aspx"&gt;immutable stack class&lt;/a&gt;. There was however one thing that was &lt;a target="_blank" href="http://www.imdb.com/title/tt0335266/"&gt;lost in translation&lt;/a&gt;. In Eric&amp;rsquo;s original code he made the class enumerable (added support for a For Each loop). Because C# has support for iterators with its &lt;span style="color:#0000ff;"&gt;yield&lt;/span&gt; keyword, that was very easy to do&amp;hellip; in C#. VB currently doesn&amp;rsquo;t have this feature so to add the same support we need to implement both the IEnumerable(Of T) and the IEnumerator(Of T), which in turn requires the implementation of the non-generic IEnumarable and IEnumerator and also the IDisposable interfaces.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Interfaces&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="340" width="604" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joacim.metablogapi/6787.Fig1_5F00_1BA690E3.jpg" alt="Fig1" border="0" title="Fig1" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/p&gt;
&lt;p&gt;As you can see from the above image, that is 7 members that we have to implement. That might sound like a lot, but fortunately it&amp;rsquo;s mainly boiler-plate code. Firstly, the &lt;em&gt;Reset&lt;/em&gt;() method of the IEnumerator interface is rarely used and in our case we will simply throw an NotImplementedException in that method. Secondly, we will end up with two &lt;em&gt;GetEnumerator&lt;/em&gt;() methods and two &lt;em&gt;Current&lt;/em&gt;() properties. But in our case we will simply make the non-generic versions of these members private and call the generic versions from them. Thirdly, in our case we will not change the code that the designer adds to the &lt;em&gt;Dispose&lt;/em&gt;() method of the IDisposable interface, except for one little detail. The designer will mark the &lt;em&gt;Dispose&lt;/em&gt;() method as &lt;em&gt;Overridable, &lt;/em&gt;but since our Stack() class is &lt;em&gt;sealed &lt;/em&gt;(NotInheritable) we only need to remove that keyword.&lt;/p&gt;
&lt;p&gt;That leaves us with only 3 members to which we need to add our logic, the &lt;em&gt;IEnumarable(Of T).GetEnumerator()&lt;/em&gt; method, the &lt;em&gt;IEnumerator(Of T).Current()&lt;/em&gt; property, and the &lt;em&gt;IEnumerator.MoveNext()&lt;/em&gt; method.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The implementation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To add support for all of this we first have to make a change to our IStack(Of T) interface.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Public Interface &lt;/span&gt;IStack(&lt;span style="color:blue;"&gt;Of &lt;/span&gt;T)
  &lt;span style="color:blue;"&gt;Inherits &lt;/span&gt;IEnumerable(&lt;span style="color:blue;"&gt;Of &lt;/span&gt;T), IEnumerator(&lt;span style="color:blue;"&gt;Of &lt;/span&gt;T)&lt;br /&gt;
&lt;br /&gt;  &lt;span style="color:blue;"&gt;Function &lt;/span&gt;Push(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;value &lt;span style="color:blue;"&gt;As &lt;/span&gt;T) &lt;span style="color:blue;"&gt;As &lt;/span&gt;IStack(&lt;span style="color:blue;"&gt;Of &lt;/span&gt;T)
  &lt;span style="color:blue;"&gt;Function &lt;/span&gt;Pop() &lt;span style="color:blue;"&gt;As &lt;/span&gt;IStack(&lt;span style="color:blue;"&gt;Of &lt;/span&gt;T)
  &lt;span style="color:blue;"&gt;Function &lt;/span&gt;Peek() &lt;span style="color:blue;"&gt;As &lt;/span&gt;T
  &lt;span style="color:blue;"&gt;ReadOnly Property &lt;/span&gt;IsEmpty() &lt;span style="color:blue;"&gt;As Boolean
End Interface&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you add this to your existing code, you will get the following in our class implementation:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joacim.metablogapi/0676.image_5F00_6410CFF4.png"&gt;&lt;img height="64" width="577" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joacim.metablogapi/6787.image_5F00_thumb_5F00_6FC61726.png" alt="image" border="0" title="image" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;To fix that simply put the text caret at the end of the &lt;em&gt;Implements &lt;/em&gt;line and press the enter key. That will allow the designer to add the empty method and property procedures that we need to implement.&lt;/p&gt;
&lt;p&gt;Since there will be two &lt;em&gt;Current()&lt;/em&gt; properties and two &lt;em&gt;GetEnumerator() &lt;/em&gt;methods, I simply rename the non-generic versions of these and make them private. From them we simply call the generic versions. In the &lt;em&gt;Reset() &lt;/em&gt;method we simply throw an NotImplementedException.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Private Function &lt;/span&gt;IEnumerator_GetEnumerator() &lt;span style="color:blue;"&gt;As &lt;/span&gt;System.Collections.IEnumerator _
    &lt;span style="color:blue;"&gt;Implements &lt;/span&gt;System.Collections.IEnumerable.GetEnumerator
  &lt;span style="color:blue;"&gt;Return &lt;/span&gt;GetEnumerator()
&lt;span style="color:blue;"&gt;End Function

Private ReadOnly Property &lt;/span&gt;IEnumerator_Current() &lt;span style="color:blue;"&gt;As Object &lt;/span&gt;_
    &lt;span style="color:blue;"&gt;Implements &lt;/span&gt;System.Collections.IEnumerator.Current
  &lt;span style="color:blue;"&gt;Get
    Return &lt;/span&gt;Current
  &lt;span style="color:blue;"&gt;End Get
End Property&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Public Sub &lt;/span&gt;Reset() &lt;span style="color:blue;"&gt;Implements &lt;/span&gt;System.Collections.IEnumerator.Reset
  &lt;span style="color:blue;"&gt;Throw New &lt;/span&gt;NotImplementedException()
&lt;span style="color:blue;"&gt;End Sub&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The important members to implement is the &lt;em&gt;GetEnumertor() &lt;/em&gt;and the&lt;em&gt; MoveNext() &lt;/em&gt;methods plus the &lt;em&gt;Current()&lt;/em&gt; read-only property. In a regular class that implements these interfaces we would simply return &lt;span style="color:#0000ff;"&gt;Me&lt;/span&gt; in the &lt;em&gt;GetEnumertor()&lt;/em&gt; method. However since our stack is immutable we can&amp;rsquo;t do that since we don&amp;rsquo;t change the current instance when we Pop a value from the stack. So instead we add a private instance of the object that we will change when needed. We also need a private field to hold the current value.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Private &lt;/span&gt;_enumerator &lt;span style="color:blue;"&gt;As &lt;/span&gt;IStack(&lt;span style="color:blue;"&gt;Of &lt;/span&gt;T) = &lt;span style="color:blue;"&gt;Me&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;Private &lt;/span&gt;_currentValue &lt;span style="color:blue;"&gt;As &lt;/span&gt;T&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see we initialize the &lt;em&gt;_enumertor&lt;/em&gt; to be a reference to the current object,&amp;nbsp; &lt;span style="color:#0000ff;"&gt;Me&lt;/span&gt;. This is what we return from the &lt;em&gt;GetEnumerator()&lt;/em&gt; method.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Public Function &lt;/span&gt;GetEnumerator() &lt;span style="color:blue;"&gt;As  &lt;/span&gt;_
    System.Collections.Generic.IEnumerator(&lt;span style="color:blue;"&gt;Of &lt;/span&gt;T) _
    &lt;span style="color:blue;"&gt;Implements &lt;/span&gt;System.Collections.Generic.IEnumerable(&lt;span style="color:blue;"&gt;Of &lt;/span&gt;T).GetEnumerator
  &lt;span style="color:blue;"&gt;Return &lt;/span&gt;_enumerator
&lt;span style="color:blue;"&gt;End Function&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the &lt;em&gt;MoveNext() &lt;/em&gt;method we are supposed to return a boolean value if we can move to the next object. In our case we simply need to check our &lt;em&gt;IsEmpty()&lt;/em&gt; property, if that is false then we can return another item. We also set the _&lt;em&gt;currentValue&lt;/em&gt; field to the current value and Pop it from the stack.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Public Function &lt;/span&gt;MoveNext() &lt;span style="color:blue;"&gt;As Boolean &lt;/span&gt;_
    &lt;span style="color:blue;"&gt;Implements &lt;/span&gt;System.Collections.IEnumerator.MoveNext
  &lt;span style="color:blue;"&gt;If Not &lt;/span&gt;_enumerator.IsEmpty &lt;span style="color:blue;"&gt;Then
    &lt;/span&gt;_currentValue = _enumerator.Peek()
    _enumerator = _enumerator.Pop()
    &lt;span style="color:blue;"&gt;Return True
  Else
    Return False
  End If
End Function&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the &lt;em&gt;Current() &lt;/em&gt;property we simply return the _&lt;em&gt;currentValue&lt;/em&gt; field that was set in the previous method.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Public ReadOnly Property &lt;/span&gt;Current() &lt;span style="color:blue;"&gt;As &lt;/span&gt;T _
    &lt;span style="color:blue;"&gt;Implements &lt;/span&gt;System.Collections.Generic.IEnumerator(&lt;span style="color:blue;"&gt;Of &lt;/span&gt;T).Current
  &lt;span style="color:blue;"&gt;Get
    Return &lt;/span&gt;_currentValue
  &lt;span style="color:blue;"&gt;End Get
End Property&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;That&amp;rsquo;s pretty much it. We can now iterate throw our Stack using code similar to this:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Public Sub &lt;/span&gt;Main()
  &lt;span style="color:blue;"&gt;Dim &lt;/span&gt;myStack &lt;span style="color:blue;"&gt;As &lt;/span&gt;IStack(&lt;span style="color:blue;"&gt;Of String&lt;/span&gt;) = Stack(&lt;span style="color:blue;"&gt;Of String&lt;/span&gt;).Empty
  &lt;span style="color:green;"&gt;&amp;#39;init the stack
  &lt;/span&gt;&lt;span style="color:blue;"&gt;For &lt;/span&gt;i &lt;span style="color:blue;"&gt;As Integer &lt;/span&gt;= 0 &lt;span style="color:blue;"&gt;To &lt;/span&gt;25
    myStack = myStack.Push(ChrW(Asc(&lt;span style="color:#a31515;"&gt;&amp;quot;A&amp;quot;)&lt;/span&gt; + i).ToString)
  &lt;span style="color:blue;"&gt;Next
  &lt;/span&gt;&lt;span style="color:green;"&gt;&amp;#39;Use a For Each loop on the stack
  &amp;#39;Note, since a stack is last in-first out,
  &amp;#39;the alphabet will be written in reversed order here
  &lt;/span&gt;&lt;span style="color:blue;"&gt;For Each &lt;/span&gt;s &lt;span style="color:blue;"&gt;As String In &lt;/span&gt;myStack
    Console.Write(s)
  &lt;span style="color:blue;"&gt;Next
End Sub&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As you&amp;rsquo;ve seen, since VB currently doesn&amp;rsquo;t support iterators in the same manner as C# does, we need to add a lot more code to our class to support it. Most of it are boiler-plate code though so it&amp;rsquo;s not as hard as it might look at a first glance. If you&amp;rsquo;re interested in learning more about how to use iterators in VB I highly recommend that you read this &lt;a target="_blank" href="http://visualstudiomagazine.com/Articles/2009/02/01/Use-Iterators-in-VB-Now.aspx"&gt;Visual Studio Magazine article&lt;/a&gt; written by &lt;a target="_blank" href="http://msmvps.com/blogs/bill/Default.aspx"&gt;Bill McCarthy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can download the code for this article &lt;a target="_blank" href="http://msmvps.com/members/Joacim/files/ImmutableStack.zip.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1721381" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.72.13.81/ImmutableStack.zip" length="109565" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/joacim/archive/tags/vb/default.aspx">vb</category><category domain="http://msmvps.com/blogs/joacim/archive/tags/visual+basic/default.aspx">visual basic</category><category domain="http://msmvps.com/blogs/joacim/archive/tags/immutable/default.aspx">immutable</category><category domain="http://msmvps.com/blogs/joacim/archive/tags/iterators/default.aspx">iterators</category><category domain="http://msmvps.com/blogs/joacim/archive/tags/IEnumerable/default.aspx">IEnumerable</category><category domain="http://msmvps.com/blogs/joacim/archive/tags/IEnumerator/default.aspx">IEnumerator</category></item></channel></rss>