1

I have an ArrayList of strings of the form "Q19_1_1", "Q19_10_1", "Q19_5_1". With the normal sort method the list will be sorted as

"Q19_1_1"  
"Q19_10_1"
"Q19_5_1"

But I would like to sort it numerically based off the second integer in name and then the third. So I would like:

"Q19_1_1"
"Q19_5_1"  
"Q19_10_1"

My Sub:

    Dim varSet As New ArrayList

    varSet.Add("Q19_1_1")
    varSet.Add("Q19_10_1")
    varSet.Add("Q19_5_1")

    varSet.Sort(New VariableComparer())

I have a IComparer:

Public Class VariableComparer
Implements IComparer(Of String)

Public Function Compare(ByVal x As String, ByVal y As String) As Integer Implements System.Collections.Generic.IComparer(Of String).Compare

    Dim varPartsX As Array
    Dim varPartsY As Array
    varPartsX = x.Split("_")
    varPartsY = y.Split("_")

    Return String.Compare(varPartsX(1), varPartsY(1))
End Function
End Class

But when I attempt to sort I get the error:

Unable to cast object of type 'VBX.VariableComparer' to type 'System.Collections.IComparer'.

VariableComparer implements IComparer but I'm guessing it can't be of type IComparer(Of String)?

How can I resolve this issue? What am I missing?

Zifendale
  • 140
  • 2
  • 12

2 Answers2

2

Using a List(Of String) also gives you access to the LINQ extensions. Specifically the OrderBy and the ThenBy extensions. You could do it something like this:

    Dim test3 As New List(Of String)({"Q19_1_1", "Q19_10_1", "Q19_5_1", "Q19_5_2"})
    test3 = test3.OrderBy(Of Integer)(Function(s) Integer.Parse(s.ToString.Split("_"c)(1))) _
                 .ThenBy(Of Integer)(Function(s2) Integer.Parse(s2.ToString.Split("_"c)(2))).ToList

Casting to Integer gives you the proper sorting without using a new IComparer interface

tinstaafl
  • 6,908
  • 2
  • 15
  • 22
1

You are correct - the issue is that you implemented IComparer(Of String), but not IComparer, which is a completely different interface.

If you switch to use a List(Of String) instead of ArrayList, it will work correctly.

This will also give you type safety within your collection.

In general, ArrayList (and the other System.Collections types) should be avoided in new development.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • May I ask why ArrayList should be avoided? Is List generally more accepted in VB.Net and used to ensure proper object types? I have mostly been using Java up until now and ArrayList in Java allows for assigning object type so I've gotten use to using ArrayList but have no problem changing that habit for VB.net. – Zifendale Sep 19 '13 at 18:01
  • 1
    @Zifendale `ArrayList` is the class that predated generics. In general, it only exists for backwards compat with .NET 1.1. Using the `System.Collections.Generic` options are always better, especially if you're using value types (no boxing), but also because the provide type safety. – Reed Copsey Sep 19 '13 at 18:09