Startsidan  ▸  Texter  ▸  Teknikblogg

Anders Hesselbom

Programmerare, skeptiker, sekulärhumanist, antirasist.
Författare till bok om C64 och senbliven lantis.
Röstar pirat.

Iterators in Visual Basic

2011-09-19

The concept of iterators is well known to C# programmers, but it is new in Visual Basic (available in Visual Studio 11), so this post is probably only interesting for VB programmers. I got some great help from my friend Roger Alsing in explaining what it is that is good about iterators.

An iterator is similar to a function that returns a collection, but an iterator allows the caller to iterate before the collection is populated. The iterator is implemented as a function with the keyword Iterator, but it is actually compiled to an object.

Public Iterator Function Test() As IEnumerable(Of Integer)

This is an iterator named Test that returns integers. The return type declared must be an IEnumerable of the type your iterator contains. This iterator returns Integer values, and therefore the return type is set to an IEnumerable(Of Integer). This is a usage example of our iterator:

For Each I As Integer In Me.Test()
   MessageBox.Show(I.ToString())
Next

Of course, a bunch of integer values will pop up on screen. But lets check the full implementation of the Test iterator.

Public Iterator Function Test() As IEnumerable(Of Integer)
   Yield 10
   Yield 20
   Yield 30
End Function

When the For Each loop is done iterating, three message boxes have popped up. They first displays 10, the second 20 and the third 30. So why not just return an array of {10, 20, 30}?

Like I mentioned, a function that returns a collection must load the collection before returning it. Imagine that you want to return 10 objects, each object takes one second to load. This gives you a pause of 10 seconds before the iteration starts. Example:

Public Function ReturnTenThings() As List(Of String)
   Dim Ret As New List(Of String)()
   For I As Integer = 0 To 9
      Threading.Thread.Sleep(1000)
      Ret.Add((I + 1).ToString())
   Next
   Return Ret
End Function

This iteration will not start until 10 seconds have passed:

For Each X As String In Me.ReturnTenThings()
   MessageBox.Show(X)
Next

If we rewrite ReturnTenThings to be an iterator, like this…

Public Iterator Function ReturnTenThings() As IEnumerable(Of String)
   Dim Ret As New List(Of String)()
   For I As Integer = 0 To 9
      Threading.Thread.Sleep(1000)
      Yield (I + 1).ToString()
   Next
End Function

…the same iteration will still take 10 seconds to complete, but it will start after just one second.

Finally, a word of warning. If you need to know before you start your iteration, how many elements it holds, don’t just read the Count property of your iterator, because that will execute your code. If you need to know, copy the elements to a list, and read the Count property of that list. This code will take 20 seconds to execute, because the iterator runs twice:

MessageBox.Show(Me.ReturnTenThings().Count.ToString())
For Each X As String In Me.ReturnTenThings()
   MessageBox.Show(X)
Next

Categories: Visual Studio 11

Leave a Reply

Your email address will not be published. Required fields are marked *



En kopp kaffe!

Bjud mig på en kopp kaffe (20:-) som tack för bra innehåll!

Bjud på en kopp kaffe!

Om...

Kontaktuppgifter, med mera, finns här.

Följ mig

Twitter Instagram
GitHub RSS

Public Service

Folkbildning om public service.

Hem   |   linktr.ee/hesselbom   |   winsoft.se   |   80tal.se   |   Filmtips