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

21.4. IComparer Interface

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.

21.4.1. System.Collections.IComparer

Naast de IComparable interface bestaat er ook een IComparer interface, of voluit System.Collections.IComparer.  Deze interface is bruikbaar om "comparers" van af te leiden die definiëren hoe verschillende objecten van een bepaald type worden vergeleken.

Deze interface is vrij eenvoudig, en heeft slechts één member, namelijk Compare :
Public Interface IComparer
    Function Compare(ByVal x As Object, ByVal y As Object) As Integer
End Interface
Deze comparer objecten kan men bijvoorbeeld doorgeven aan Sort methods, van bijvoorbeeld de Array klasse, om aan te geven dat men van het normale vergelijkingsgedrag, gedefinieerd door de IComparable.CompareTo implementatie, wil gaan afwijken.

De returnwaarde van deze Compare method zou :
- negatief (< 0) moeten zijn indien x "kleiner" is dan y
- nul moeten zijn indien x "gelijk" is aan y
- positief (> 0) moeten zijn indien x "groter" is dan y

Kleiner, groter of gelijk moet je niet letterlijk nemen.  In deze context van een sorteermethod wordt daar bijvoorbeeld mee bedoeld dat ze respectievelijk voor, na of op dezelfde ordinale plaats komen.

In onderstaand voorbeeld zie je hoe bij de eerste call naar Array.Sort (1), de Counter elementen gewoon worden gesorteerd op basis van hun Value.  Dit is immers wat de IComparable.CompareTo implementatie had aangegeven.

De call naar Array.Sort met een IComparer argumentwaarde (2), zal hier de Counter elementen sorteren op hun StepValue, wat door de implementatie van de IComparer.Compare method is aangegeven.
Visual Basic 2012 Broncode - Codevoorbeeld 473
Option Strict On

Imports System.Collections

Namespace IComparerInterface
    Public Class Counter : Implements IComparable
        Public Sub New(ByVal value As Integer)
            _Value = value
            _StepValue = 1
        End Sub
        Private _Value As Integer
        Public ReadOnly Property Value() As Integer
            Get
                Value = _Value
            End Get
        End Property
        Public Property StepValue As Integer
        Public Sub Raise()
            _Value += StepValue
        End Sub
        Public Overrides Function ToString() As String
            ToString = Value.ToString() & "/" & StepValue.ToString()
        End Function
        Private Function CompareTo(ByVal obj As Object) As Integer _
                                                Implements IComparable.CompareTo
            If Not TypeOf obj Is Counter Then
                Throw New ArgumentException("An invalid argument was " & _
                         "specified.  An argument of type Counter is required.")
            Else
                CompareTo = CompareTo(DirectCast(obj, Counter))
            End If
        End Function
        Public Function CompareTo(ByVal other As Counter) As Integer
            If other IsNot Nothing Then
                CompareTo = 1
            Else
                CompareTo = Me.Value.CompareTo(other.Value)
            End If
        End Function
    End Class
    Public Class CounterStepValueComparer : Implements IComparer
        Public Function Compare(ByVal x As Object, ByVal y As Object) _
                                         As Integer Implements IComparer.Compare
            If x IsNot Nothing AndAlso y Is Nothing Then                   ' (3)
                Return 1
            ElseIf x Is Nothing AndAlso y IsNot Nothing Then               ' (4)
                Return -1
            ElseIf x IsNot Nothing AndAlso y IsNot Nothing Then
                If TypeOf x Is Counter AndAlso TypeOf y Is Counter Then    ' (5)
                    Dim a As Counter = DirectCast(x, Counter)
                    Dim b As Counter = DirectCast(y, Counter)
                    Compare = a.StepValue.CompareTo(b.StepValue)
                Else
                    Throw New ArgumentException("x and y are of different " & _
                 "types and neither one can handle comparisons with the other.")
                End If
            End If
        End Function
    End Class
    Public Class Client
        Public Shared Sub Main()
            Dim array1 As Counter() = _
                          New Counter() {New Counter(1) With {.StepValue = 3}, _
                                         New Counter(2) With {.StepValue = 2}, _
                                         New Counter(3) With {.StepValue = 1}}
            '
            Array.Sort(array1)                                             ' (1)
            PrintArray(array1) ' 1/3 2/2 3/1
            '
            Dim comparer1 As IComparer = New CounterStepValueComparer
            '
            Array.Sort(array1, comparer1)                                  ' (2)
            PrintArray(array1) ' 3/1 2/2 1/3
            '
            Console.ReadLine()
        End Sub
        Public Shared Sub PrintArray(ByVal array As Array)
            For Each element As Object In array
                Console.Write(element.ToString() & " ")
            Next
            Console.WriteLine()
        End Sub
    End Class
End Namespace
Console Application Output
1/3 2/2 3/1
3/1 2/2 1/3
Elke object wordt als "groter" beschouwd dan Nothing ((3) en (4)).

Indien men toch probeert objecten van onvergelijkbare types te vergelijken, dan treedt er typisch een ArgumentException op (5).

Het werken met comparer objecten is ook van toepassing indien je bijvoorbeeld niet beschikt over de sourcecode van de itemtype, maar toch wil gaan aangeven op basis van wat, elementen van dat type, worden gesorteerd.

21.4.2. System.Collections.Generic.IComparer(Of T)

De System.Collections.IComparer interface is niet strongly typed.  Je kan aan de Compare method argumentwaardes meegeven van eender welk type gezien er gewerkt wordt met Object parameters.

Een strongly typed variant van IComparer is de System.Collections.Generic.IComparer(Of T) interface, deze wordt verderop behandeld in het hoofdstuk over genericiteit.

21.4.3. System.Collections.Generic.CaseInsensitiveComparer

We hoeven ook niet altijd zelf een comparer te definiëren, er bestaan immers een aantal voorgedefinieerd, bijvoorbeeld de System.Collections.Generic.CaseInsensitiveComparer klasse die reeds de IComparer interface implementeren.

Deze zal Strings vergelijken zonder rekening te houden met hoofdletters of kleine letters :
Visual Basic 2012 Broncode - Codevoorbeeld 474
Namespace CaseInsensitiveComparerExample
    Public Class Client
        Public Shared Sub Main()
            Dim array1 As String() = New String() {"B", "b", "a", "A"}
            '
            Array.Sort(array1)
            IComparerInterface.Client.PrintArray(array1) ' a A b B
            '
            Array.Sort(array1, New CaseInsensitiveComparer)
            IComparerInterface.Client.PrintArray(array1) ' A a B b
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
a A b B
A a B b

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