How to use the IComparable and the IComparer interfaces in Visual Basic .NET or in Visual Basic 2005

This article refers to the following Microsoft .NET Framework Class Library namespace:
  • System.Collections

Summary

This step-by-step article demonstrates how to use two interfaces: IComparer and IComparable. These interfaces are addressed in the same article for two reasons:
  • These interfaces are frequently used together.
  • Although the interfaces are similar (and have similar names), the purposes that they serve are a little different.
If you have an array of types (such as the string or the integer types) that already support IComparer, you can sort that array without providing any explicit reference to IComparer. In this case, the elements of the array are cast to the default implementation of IComparer (Comparer.Default) for you. However, if want to sort and to compare your custom objects, you must implement either or both of these interfaces.

IComparable Interface

The IComparable interface provides a method to compare two objects of a particular type. Use this interface if you want to order your object.

Think of IComparable as providing a default sort order for your objects. For example, if you have an array of objects of your type, and if you call the Sort method on that array, you can use the IComparable interface to compare the objects during the sort. When you implement the IComparable interface, you must also implement the CompareTo method. For example:
Function CompareTo(ByVal obj As Object) As Integer Implements IComparable.CompareTo
Dim c As car = CType(obj, car)
Return String.Compare(Me.mmake, c.mmake)
End Function
The comparison in the method differs depending on the data type of the value that is being compared. This example uses the String.Compare method because the property that is being compared is a string.

IComparer Interface

The IComparer interface provides additional comparison mechanisms. For example, you may want to order your class on several fields or properties, by ascending and descending order on the same field, or both.

To use IComparer, follow these steps:
  1. Declare a class that implements IComparer, and implement the Compare method. For example:
    Private Class sortYearDescendingHelper : Implements IComparer
    Function Compare(ByVal a As Object, ByVal b As Object) As Integer Implements IComparer.Compare
    Dim c1 As car = CType(a, car)
    Dim c2 As car = CType(b, car)

    If (c1.year < c2.year) Then
    Return 1
    End If

    If (c1.Year > c2.Year) Then
    Return -1
    Else
    Return 0
    End If
    End Function
    End Class
    Notice that the IComparer.Compare method requires a tertiary comparison. 1, 0, or -1 is returned, depending on whether one value is greater than, equal to, or less than the other.

    NOTE: You can change the sort order (ascending versus descending) by switching the logical operators in this method.
  2. Declare a method that returns an instance of your IComparer object. This example uses the object as the second argument when you call the overloaded Array.Sort method that accepts IComparer.
    Public Shared Function sortYearAscending() As IComparer
    Return CType(New sortYearAscendingHelper(), IComparer)
    End Function
The use of IComparer is not limited to arrays, it is accepted as an argument in a number of different collection and control classes.

Step-by-Step Example

The example in this section demonstrates how to use IComparer and IComparable. This example creates a class named car. The car object has the two properties: make and year. This example uses the IComparable interface to sort on the make field in ascending order. This example then uses the IComparer interface to sort on the make field in descending order. This example also provides ascending and descending sorts for the year property through the use of IComparer.
  1. Start Microsoft Visual Studio .NET or Microsoft Visual Studio 2005.
  2. On the File menu, point to New, and then click Project.
  3. Click Visual Basic Projects under Project Types, click Console Application under Templates, and then type ConsoleEnum in the Name box.

    Note In Visual Basic 2005, click Visual Basic under Project Types.
  4. In Solution Explorer, right-click Module1.vb, click Rename, and then type Host.vb.
  5. Replace the code in Host.vb with the following code:
    Module Module1

    Sub Main()
    Dim c As car
    Dim arrayOfCars() As car = _
    { _
    New car("Ford", 1992), _
    New car("Fiat", 1988), _
    New car("Buick", 1932), _
    New car("Ford", 1932), _
    New car("Dodge", 1999), _
    New car("Honda", 1977) _
    }

    Dim t As String = vbTab & vbTab
    Dim n As String = vbCrLf

    Console.WriteLine("Array - Unsorted" & n)
    For Each c In arrayOfCars
    Console.WriteLine(c.Make & t & c.Year)
    Next
    Array.Sort(arrayOfCars)
    Console.WriteLine(n & "Array - Sorted by Make (Ascending - IComparable)" & n)
    For Each c In arrayOfCars
    Console.WriteLine(c.Make & t & c.Year)
    Next
    Array.Sort(arrayOfCars, car.sortYearAscending())
    Console.WriteLine(n & "Array - Sorted by Year (Ascending - IComparer)" & n)
    For Each c In arrayOfCars
    Console.WriteLine(c.Make & t & c.Year)
    Next

    Array.Sort(arrayOfCars, car.sortMakeDescending())
    Console.WriteLine(n & "Array - Sorted by Make (Descending - IComparer)" & n)
    For Each c In arrayOfCars
    Console.WriteLine(c.Make & t & c.Year)
    Next

    Array.Sort(arrayOfCars, car.sortYearDescending())
    Console.WriteLine(n & "Array - Sorted by Year (Descending - IComparer)" & n)
    For Each c In arrayOfCars
    Console.WriteLine(c.Make & t & c.Year)
    Next

    Console.ReadLine()

    End Sub
    End Module
  6. On the Project menu, click Add Class.
  7. In the Add New Item dialog box, type car in the Name box, and then click Open.

    Note In Visual Studio 2005, click Add instead of Open.
  8. Replace the code in car.vb with the following code:
    Option Explicit On 
    Option Strict On

    Imports System.Collections

    Public Class car : Implements IComparable
    ' Nested classes to do secondary sorts
    Private Class sortYearAscendingHelper : Implements IComparer
    Function Compare(ByVal a As Object, ByVal b As Object) As Integer Implements IComparer.Compare
    Dim c1 As car = CType(a, car)
    Dim c2 As car = CType(b, car)

    If (c1.year > c2.year) Then
    Return 1
    End If

    If (c1.Year < c2.Year) Then
    Return -1
    Else
    Return 0
    End If
    End Function
    End Class

    Private Class sortYearDescendingHelper : Implements IComparer
    Function Compare(ByVal a As Object, ByVal b As Object) As Integer Implements IComparer.Compare
    Dim c1 As car = CType(a, car)
    Dim c2 As car = CType(b, car)

    If (c1.year < c2.year) Then
    Return 1
    End If

    If (c1.Year > c2.Year) Then
    Return -1
    Else
    Return 0
    End If
    End Function
    End Class

    Private Class sortMakeDescendingHelper : Implements IComparer
    Function Compare(ByVal a As Object, ByVal b As Object) As Integer Implements IComparer.Compare
    Dim c1 As car = CType(a, car)
    Dim c2 As car = CType(b, car)

    Return String.Compare(c2.Make, c1.Make)
    End Function
    End Class
    ' End nested classes.

    Private myear As Integer
    Private mmake As String

    Public Sub New(ByVal Make As String, ByVal Year As Integer)
    mmake = Make
    myear = Year
    End Sub

    Public Property Year() As Integer
    Get
    Return myear
    End Get

    Set(ByVal Value As Integer)
    myear = Value
    End Set
    End Property

    Public Property Make() As String
    Get
    Return mmake
    End Get

    Set(ByVal Value As String)
    mmake = Value
    End Set
    End Property

    Function CompareTo(ByVal obj As Object) As Integer Implements IComparable.CompareTo
    Dim c As car = CType(obj, car)

    Return String.Compare(Me.mmake, c.mmake)
    End Function

    Public Shared Function sortYearAscending() As IComparer
    Return CType(New sortYearAscendingHelper(), IComparer)
    End Function

    Public Shared Function sortYearDescending() As IComparer
    Return CType(New sortYearDescendingHelper(), IComparer)
    End Function

    Public Shared Function sortMakeDescending() As IComparer
    Return CType(New sortMakeDescendingHelper(), IComparer)
    End Function
    End Class
  9. Run the project. Notice that the following output appears in the Console window:

    Array - Unsorted

    Ford 1992
    Fiat 1988
    Buick 1932
    Ford 1932
    Dodge 1999
    Honda 1977

    Array - Sorted by Make (Ascending - IComparable)

    Buick 1932
    Dodge 1999
    Fiat 1988
    Ford 1932
    Ford 1992
    Honda 1977

    Array - Sorted by Year (Ascending - IComparer)

    Ford 1932
    Buick 1932
    Honda 1977
    Fiat 1988
    Ford 1992
    Dodge 1999

    Array - Sorted by Make (Descending - IComparer)

    Honda 1977
    Ford 1932
    Ford 1992
    Fiat 1988
    Dodge 1999
    Buick 1932

    Array - Sorted by Year (Descending - IComparer)

    Dodge 1999
    Ford 1992
    Fiat 1988
    Honda 1977
    Buick 1932
    Ford 1932
Propriedades

ID do Artigo: 321292 - Última Revisão: 6 de dez de 2006 - Revisão: 1

Comentários