Visual Basic 2012 Voorbeelden
   

visual basic 2012 broncode voorbeelden

Blijf op de hoogte van de recente aanpassingen op vbvoorbeelden!

Microsoft Visual Studio 2012Microsoft Developers Network - Visual BasicMicrosoft .NET Framework

22.2. Collecties en de IEnumerable en ICollection Interfaces

Print Email Deel op Twitter Deel op Facebook

Dit artikel is gepubliceerd op maandag 15 oktober 2012 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.

Veronderstel volgende item types :
Visual Basic 2012 Broncode - Codevoorbeeld 516
Option Strict On

Imports System.Collections

Public Class Finger
End Class
Public Class Thumb : Inherits Finger
End Class
Public Class IndexFinger : Inherits Finger
End Class
Public Class MiddleFinger : Inherits Finger
End Class
Public Class RingFinger : Inherits Finger
End Class
Public Class LittleFinger : Inherits Finger
End Class
Een type als onderstaande Hand kan je zien als een verzameling of collectie van Fingers :
Visual Basic 2012 Broncode - Codevoorbeeld 517
Namespace SimpleHand
    Public Class Hand
        Public ReadOnly Thumb As New Thumb
        Public ReadOnly IndexFinger As New IndexFinger
        Public ReadOnly MiddleFinger As New MiddleFinger
        Public ReadOnly RingFinger As New RingFinger
        Public ReadOnly LittleFinger As New LittleFinger
    End Class
End Namespace
Met bovenstaand collectietype kunnen we weinig aan.  Het is bijvoorbeeld niet mogelijk over de elementen van deze collectie te itereren.

22.2.1. De System.Collections.IEnumerable Interface

Om dit toch te kunnen moeten we de IEnumerable interface implementeren.

Deze is als volgt gedefinieerd :
Public Interface IEnumerable
    Function GetEnumerator() As IEnumerator
End Interface
De IEnumerator interface ziet er zo uit :
Public Interface IEnumerator
    Function MoveNext() As Boolean
    ReadOnly Property Current() As Object
    Sub Reset()
End Interface
In onderstaand voorbeeld zien we hoe we de IEnumerable interface in ons type Hand kunnen implementeren :
Visual Basic 2012 Broncode - Codevoorbeeld 518
Namespace IEnumerableHand
    Public Class Hand : Implements IEnumerable
        Public ReadOnly Thumb As New Thumb
        Public ReadOnly IndexFinger As New IndexFinger
        Public ReadOnly MiddleFinger As New MiddleFinger
        Public ReadOnly RingFinger As New RingFinger
        Public ReadOnly LittleFinger As New LittleFinger
        Public Function GetEnumerator() As IEnumerator _
                                            Implements IEnumerable.GetEnumerator
            GetEnumerator = New HandEnumerator(Me)
        End Function
    End Class
    Public Class HandEnumerator : Implements IEnumerator
        Public Sub New(ByVal items As Hand)
            _Items = items
        End Sub
        Private _Items As Hand
        Private _Cursor As Finger
        Public ReadOnly Property Current() As Object _
                                                  Implements IEnumerator.Current
            Get
                Current = _Cursor
            End Get
        End Property
        Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
            MoveNext = True
            If _Cursor Is Nothing Then
                _Cursor = _Items.Thumb
            ElseIf _Cursor Is _Items.Thumb Then
                _Cursor = _Items.IndexFinger
            ElseIf _Cursor Is _Items.IndexFinger Then
                _Cursor = _Items.MiddleFinger
            ElseIf _Cursor Is _Items.MiddleFinger Then
                _Cursor = _Items.RingFinger
            ElseIf _Cursor Is _Items.RingFinger Then
                _Cursor = _Items.LittleFinger
            Else ' _Items.LittleFinger Then
                _Cursor = Nothing
            End If
            If _Cursor Is Nothing Then MoveNext = False
        End Function
        Public Sub Reset() Implements IEnumerator.Reset
            _Cursor = Nothing
        End Sub
    End Class
End Namespace
Meer details over de interfaces IEnumerable en IEnumerator vind je in de desbetreffende topics.

Eens de IEnumerable interface is geïmplementeerd in ons type Hand kan men een object van dit type in enumereerbare context gebruiken.

Bijvoorbeeld in een For Each iteratie :
Visual Basic 2012 Broncode - Codevoorbeeld 519
Namespace IEnumerableHand
    Class Client
        Public Shared Sub Main()
            Dim hand1 As IEnumerable = New Hand
            For Each element As Object In hand1
                Console.WriteLine(element)
            Next
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
Thumb
IndexFinger
MiddleFinger
RingFinger
LittleFinger

22.2.2. De System.Collections.ICollection Interface

Naast het enumeren over een collectie, is ook de mogelijkheid om het aantal elementen op te vragen of de mogelijkheid om de elementen over te kopiëren naar een array, veel gevraagd functionaliteiten voor collecties.

Dit is ondermeer waarin de ICollection interface voorziet :
Public Interface ICollection : Inherits IEnumerable
    Sub CopyTo(ByVal array As Array, ByVal index As Integer)
    ReadOnly Property Count() As Integer
End Interface
Bemerk dat de ICollection interface overerft van de IEnumerable interface.
Indien we ICollection implementeren, moeten we bijgevolg ook IEnumerable in dat type implementeren.

Een mogelijke ICollection implementatie voor een type als Hand zou er zo kunnen uitzien :
Visual Basic 2012 Broncode - Codevoorbeeld 520
Namespace ICollectionHand
    Public Class Hand : Implements ICollection
        Private _Items As Finger() = New Finger() {New Thumb, New IndexFinger, _
                                                   New MiddleFinger, _
                                                   New RingFinger, _
                                                   New LittleFinger}
        Public Function GetEnumerator() As IEnumerator _
                                            Implements ICollection.GetEnumerator
            GetEnumerator = _Items.GetEnumerator()
        End Function
        Public Sub CopyTo(ByVal array As System.Array, ByVal index As Integer) _
                                                   Implements ICollection.CopyTo
            _Items.CopyTo(array, index)
        End Sub
        Public ReadOnly Property Count() As Integer Implements ICollection.Count
            Get
                Count = _Items.Count
            End Get
        End Property
        Public ReadOnly Property IsSynchronized() As Boolean _
                                           Implements ICollection.IsSynchronized
            Get
                IsSynchronized = _Items.IsSynchronized
            End Get
        End Property
        Public ReadOnly Property SyncRoot() As Object _
                                                 Implements ICollection.SyncRoot
            Get
                SyncRoot = _Items.SyncRoot
            End Get
        End Property
    End Class
End Namespace
Om bovenstaande ICollection implementatie te vereenvoudigen is hier intern gebruik gemaakt van een Array, meer specifiek een Finger().
Omdat Array zelf reeds een ICollection is, kunnen we de implementatie van de methods GetEnumerator, CopyTo, Count, IsSynchronized en SyncRoot voor onze Hand delegeren naar de gelijknamige implementaties van de Array klasse.

Eens klasse Hand de interface ICollection implementeert kunnen instanties van deze klasse in een "collection context" gebruikt worden.
Veel voorgedefinieerde collectietype bijvoorbeeld, zoals Types System.Collections.Queue en Stack, die overigens zelf de interface ICollection implementeren, beschikken over een constructor waar je een ICollection kan doorgeven.
Dit om meteen bij creatie van dergelijke collecties een aantal initiële elementen te voorzien.
Visual Basic 2012 Broncode - Codevoorbeeld 521
Namespace ICollectionHand
    Class Client
        Public Shared Sub Main()
            Dim hand1 As ICollection = New Hand
            '
            Dim queue1 As New Queue(hand1)
            For Each element As Object In queue1
                Console.WriteLine(element)
            Next
            Console.WriteLine()
            '
            Dim stack1 As New Stack(hand1)
            For Each element As Object In queue1
                Console.WriteLine(element)
            Next
            Console.WriteLine()
            '
            Dim fingersArray1(4) As Finger
            hand1.CopyTo(fingersArray1, 0)
            For Each element As Finger In fingersArray1
                Console.WriteLine(element)
            Next
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
Thumb
IndexFinger
MiddleFinger
RingFinger
LittleFinger

Thumb
IndexFinger
MiddleFinger
RingFinger
LittleFinger

Thumb
IndexFinger
MiddleFinger
RingFinger
LittleFinger

22.2.3. De System.Collections.ReadOnlyCollectionBase Klasse

Eenvoudiger dan het implementeren van de ICollection interface is het overerven van de abstracte ReadOnlyCollectionBase klasse.

Deze implementeert reeds de ICollection interface, wat ervoor zorgt dat wij zelf de members uit deze interface niet meer hoeven te implementeren.

De definitie van de ReadOnlyCollectionBase ziet er ongeveer zo uit :
Visual Basic 2012 Broncode - Codevoorbeeld 522
Namespace ReadOnlyCollectionBaseHand
    Public MustInherit Class ReadOnlyCollectionBase : Implements ICollection
        Private list As ArrayList
        Protected ReadOnly Property InnerList() As ArrayList
            Get
                If (Me.list Is Nothing) Then
                    Me.list = New ArrayList
                End If
                Return Me.list
            End Get
        End Property
        Public Overridable Function GetEnumerator() As IEnumerator _
                                            Implements ICollection.GetEnumerator
            Return Me.InnerList.GetEnumerator
        End Function
        Private Sub CopyTo(ByVal array As Array, ByVal index As Integer) _
                                                   Implements ICollection.CopyTo
            Me.InnerList.CopyTo(array, index)
        End Sub
        Public Overridable ReadOnly Property Count() As Integer _
                                                    Implements ICollection.Count
            Get
                Return Me.InnerList.Count
            End Get
        End Property
        Private ReadOnly Property IsSynchronized() As Boolean _
                                           Implements ICollection.IsSynchronized
            Get
                Return Me.InnerList.IsSynchronized
            End Get
        End Property
        Private ReadOnly Property SyncRoot() As Object _
                                                 Implements ICollection.SyncRoot
            Get
                Return Me.InnerList.SyncRoot
            End Get
        End Property
    End Class
End Namespace
Onze Hand ICollection kan dus een stuk eenvoudiger door van de klasse ReadOnlyCollectionBase over te erven.
Visual Basic 2012 Broncode - Codevoorbeeld 523
Namespace ReadOnlyCollectionBaseHand
    Public Class Hand : Inherits ReadOnlyCollectionBase
        Public Sub New()
            InnerList.AddRange(New Finger() {New Thumb, New IndexFinger, _
                                             New MiddleFinger, New RingFinger, _
                                             New LittleFinger})
        End Sub
    End Class
End Namespace
Namespace ReadOnlyCollectionBaseHand
    Class Client
        Public Shared Sub Main()
            Dim hand1 As ICollection = New Hand
            '
            Dim queue1 As New Queue(hand1)
            For Each element As Object In queue1
                Console.WriteLine(element)
            Next
            '
            Dim stack1 As New Stack(hand1)
            For Each element As Object In queue1
                Console.WriteLine(element)
            Next
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
Thumb
IndexFinger
MiddleFinger
RingFinger
LittleFinger
Thumb
IndexFinger
MiddleFinger
RingFinger
LittleFinger
De ReadOnlyCollectionBase klasse is voorzien om enkel-lees collecties op te baseren.
Verderop bespreken we ook nog de System.Collections.CollectionBase klasse, voorzien om strongly typed editeerbare list collecties op te baseren.

Dit artikel is gepubliceerd op maandag 15 oktober 2012 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.