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. .NET (Core and Framework)
  4. Ways of implenting IEnumerable in VB

Ways of implenting IEnumerable in VB

Scheduled Pinned Locked Moved .NET (Core and Framework)
databasetutorialquestion
3 Posts 2 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.
  • M Offline
    M Offline
    M Badger
    wrote on last edited by
    #1

    OK, I cannot get my head around the whether there is a difference between the 'classic' (perhaps long winded) way of doing it, multiple classes and the 'new' Yield route to (apparently) the same end. I can understand the classic route (I think), see the code below. Yield confuses the heck out of me, if I understand it correctly then it's absolutely genius, I get the idea of a state machine (I think) and logically it sort of makes sense but I am not at all confident. Can it possibly be this simple? You just make that one method as simple or complex as necessary for your situation? (Warning, silly example since arrays can already be enumerated, but it's easy to demo)

    Public Class YieldExample
    Implements IEnumerable

    Private \_Thing As Double()
    
    Public Iterator Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
        If IsNothing(Me.\_Thing) Then
            Throw New InvalidOperationException()
        End If
    
        For Index As Integer = 0 To Me.\_Thing.GetUpperBound(0)
            Yield Me.\_Thing(Index)
        Next
    End Function
    

    End Class

    What I understand to be the 'old way'.

    Public Class ExampleEnumerable
    Implements IEnumerable(Of Double)

    Private \_Thing As Double()
    
    Public Function GetEnumerator() As IEnumerator(Of Double) Implements IEnumerable(Of Double).GetEnumerator
        Return New ExampleEnumerator(Me.\_Thing)
    End Function
    
    Public Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
        Return Me.GetEnumerator
    End Function
    

    End Class

    Public Class ExampleEnumerator
    Implements IEnumerator(Of Double)

    Private \_Thing As Double()
    Private \_Index As Integer
    Private \_curItem As Double
    
    Public Sub New(ByVal Thing As Double())
        Me.\_Thing = Thing
        Me.\_Index = -1
        Me.\_curItem = Nothing
    End Sub
    
    Public ReadOnly Property Current As Double Implements IEnumerator(Of Double).Current
        Get
            If IsNothing(Me.\_curItem) Then
                Throw New InvalidOperationException()
            End If
            Return Me.\_curItem
        End Get
    End Property
    
    Public ReadOnly Property Current1 As Object Implements IEnumerator.Current
        Get
            Return Me.Current
        End Get
    End Property
    
    Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
        'If we are already at the end then return false
        If Me.\_I
    
    M 1 Reply Last reply
    0
    • M M Badger

      OK, I cannot get my head around the whether there is a difference between the 'classic' (perhaps long winded) way of doing it, multiple classes and the 'new' Yield route to (apparently) the same end. I can understand the classic route (I think), see the code below. Yield confuses the heck out of me, if I understand it correctly then it's absolutely genius, I get the idea of a state machine (I think) and logically it sort of makes sense but I am not at all confident. Can it possibly be this simple? You just make that one method as simple or complex as necessary for your situation? (Warning, silly example since arrays can already be enumerated, but it's easy to demo)

      Public Class YieldExample
      Implements IEnumerable

      Private \_Thing As Double()
      
      Public Iterator Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
          If IsNothing(Me.\_Thing) Then
              Throw New InvalidOperationException()
          End If
      
          For Index As Integer = 0 To Me.\_Thing.GetUpperBound(0)
              Yield Me.\_Thing(Index)
          Next
      End Function
      

      End Class

      What I understand to be the 'old way'.

      Public Class ExampleEnumerable
      Implements IEnumerable(Of Double)

      Private \_Thing As Double()
      
      Public Function GetEnumerator() As IEnumerator(Of Double) Implements IEnumerable(Of Double).GetEnumerator
          Return New ExampleEnumerator(Me.\_Thing)
      End Function
      
      Public Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
          Return Me.GetEnumerator
      End Function
      

      End Class

      Public Class ExampleEnumerator
      Implements IEnumerator(Of Double)

      Private \_Thing As Double()
      Private \_Index As Integer
      Private \_curItem As Double
      
      Public Sub New(ByVal Thing As Double())
          Me.\_Thing = Thing
          Me.\_Index = -1
          Me.\_curItem = Nothing
      End Sub
      
      Public ReadOnly Property Current As Double Implements IEnumerator(Of Double).Current
          Get
              If IsNothing(Me.\_curItem) Then
                  Throw New InvalidOperationException()
              End If
              Return Me.\_curItem
          End Get
      End Property
      
      Public ReadOnly Property Current1 As Object Implements IEnumerator.Current
          Get
              Return Me.Current
          End Get
      End Property
      
      Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
          'If we are already at the end then return false
          If Me.\_I
      
      M Offline
      M Offline
      MicroVirus
      wrote on last edited by
      #2

      Dear Mike, I realise this is a late answer, so maybe you've already figured this out. But maybe it's still worth something, so here goes: I think the short answer is that Yield is absolutely genius. The 'classic' way as you put it actually is the same implementation over and over again, where only the return value varies. What yield does for you is that it allows you to construct an IEnumerable directly from a function (using Yield statements), such that every time MoveNext() is called, the function takes off where it left off until the next Yield statement. So, yes, you can just use yield whenever you want :) I think the only possible issue with it is that it's probably slower than a proper custom ('classic') implementation, so if you have A LOT of elements AND you notice a performance bottleneck in enumeration THEN you might consider getting your hands dirty. Best regards, Richard

      M 1 Reply Last reply
      0
      • M MicroVirus

        Dear Mike, I realise this is a late answer, so maybe you've already figured this out. But maybe it's still worth something, so here goes: I think the short answer is that Yield is absolutely genius. The 'classic' way as you put it actually is the same implementation over and over again, where only the return value varies. What yield does for you is that it allows you to construct an IEnumerable directly from a function (using Yield statements), such that every time MoveNext() is called, the function takes off where it left off until the next Yield statement. So, yes, you can just use yield whenever you want :) I think the only possible issue with it is that it's probably slower than a proper custom ('classic') implementation, so if you have A LOT of elements AND you notice a performance bottleneck in enumeration THEN you might consider getting your hands dirty. Best regards, Richard

        M Offline
        M Offline
        M Badger
        wrote on last edited by
        #3

        Thank you :-) Appreciated whatever the timing :-)

        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