Sorting a list / Implementation of IComparable

  • 13 years ago

    I have a list of objects. When trying to sort the list, I receive an error "error while comparing two elements of the array". Inner Exception is "At least one object must implement IComparable." (Please note: I'm using the german version of VB Express and therefor I had to re-translate the error messages. So the original english error messages may be a little different). Here's the code I have so far:

    Public Class cl_country
        Private m_Name As String

        Public Property Name() As String
            Get
                Return m_Name
            End Get
            Set(ByVal value As String)
                m_Name = value
            End Set
        End Property






    End Class

     

     

    Public Class Form1
        Private my_List As New List(Of cl_country)
        Private country_1 As New cl_country
        Private country_2 As New cl_country
        Private country_3 As New cl_country
        Private z As Integer




        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Init()
            GUI_Output(ListBox1)
            my_List.Sort()
            GUI_Output(ListBox2)
        End Sub




        Private Sub Init()
            country_1.Name = "Germany"
            country_2.Name = "Brazil"
            country_3.Name = "UK"
            my_List.Add(country_1)
            my_List.Add(country_2)
            my_List.Add(country_3)
        End Sub






        Private Sub GUI_Output(ByVal a_listbox As ListBox)
            a_listbox.Items.Clear()
            For z = 1 To my_List.Count
                a_listbox.Items.Add(my_List.Item(z - 1).Name)
            Next
        End Sub




    End Class

     

    I have understood that VB is unable to sort objects and that I need to provide a method to do so. I had a look at IComparable and it's examples in the Object Browser but I did not understand the examples. Can anyone help me with this ?

  • 13 years ago

    Classes that implement IComparable have a CompareTo method.  If you take a look at an integer or string or many other objects you'll see they have this method.  All the CompareTo method does is accepts another object and returns a value indicating the current objects relative position with the object passed.  The return value would be 1, 0, -1 for "greater then", "equal to", "less then".  It's this method that allows any object to be sorted becaues all you need to know in order to sort a list of objects is how one of these objects compares to another.

    In order to use the interface just type "implements IComparable(of cl_country)" just under your class declration and then hit enter.  When you hit enter the appropriate method declarations for the interface will be created for you.  In this case there is only one method 'CompareTo'.  It's your responsibilty to add the code into this method that compares the current object with the object passed and return a relative value.

    An example may help.

    Public Class Form1
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            ' Create three people objects
            Dim obj1 As New Person("FirstPerson", 29)
            Dim obj2 As New Person("SecondPerson", 47)
            Dim obj3 As New Person("ThirdPerson", 10)
    
            ' Create a list of people and add the objects I've created
            Dim people As New List(Of Person)
            people.AddRange(New Person() {obj1, obj2, obj3})
    
            ' Sort the list
            people.Sort()
    
            ' Display each of the people in the list showing they've been
            ' sorted is Ascending order by age
            For Each p As Person In people
                Console.WriteLine("{0} is {1} years old", p.Name, p.Age)
            Next
        End Sub
    End Class
    
    ' A person with a name and age
    ' This class uses IComparable so it can be sorted
    Public Class Person
        Implements IComparable(Of Person)
    
        Public Age As Integer       ' Persons age
        Public Name As String       ' Persons name
    
    
        ' Constructor
        Public Sub New(ByVal name As String, ByVal age As Integer)
            Me.Age = age
            Me.Name = name
        End Sub
    
        ' CompareTo method is part of the IComparable interface
        ' This method will return the relative value of this object with the passed
        ' object.  1 = Greater then   0 = Equal To   -1 = Less then
        ' I'll be sorting on age so this method will compare the age fields
        Public Function CompareTo(ByVal other As Person) As Integer Implements System.IComparable(Of Person).CompareTo
            ' I've actually used more code here then I need to drive the
            ' example home.  You can clearly see how I've done the comparison
            ' with this if statement.
            If Me.Age > other.Age Then
                Return 1
            ElseIf Me.Age = other.Age Then
                Return 0
            Else
                Return -1
            End If
    
            ' In this case I really could have used the integers CompareTo method
            ' and simply used the next commented line of code instead of
            ' the if statement above.
    
            'Return Me.Age.CompareTo(other.Age)
    
            ' The if statement above will cause my peson objects to be sorted in Ascending order
            ' However this could easily be changed with the following commented code.
            ' Notice how I'm now passing a -1 when this object's age is greater then the passed object's age
            ' and a 1 when this object is less then the other object.  By reversing the return value I'll reverse
            ' the sort order
    
            'If Me.Age > other.Age Then
            '    Return -1
            'ElseIf Me.Age = other.Age Then
            '    Return 0
            'Else
            '    Return 1
            'End If
        End Function
    End Class
  • 13 years ago
    Many thanks for your help TwoFaced. That was exactly what I was looking for.

Post a reply

Enter your message below

Sign in or Join us (it's free).

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Some people, when confronted with a problem, think "I know, I’ll use regular expressions." Now they have two problems.” - Jamie Zawinski