Search code examples
c#vb.netstring-comparisonicomparableicomparer

IComparer problem in vb.net but same working in C#


I found running code for Natural Sort Alpha-numeric like Windows Explorer in C# and https://dotnetfiddle.net/kBP7EW

Dmitry Bychenko wrote some very good code in C# which is 100% working but somehow is not working in VB.NET. I'm unable to understand what was missed during conversion.

I just converted it into VB.NET, but getting multiple errors:

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text.RegularExpressions

Public NotInheritable Class NaturalComparer
    Implements IComparer(Of String)

    Private Shared Function CompareChunks(ByVal x As String, ByVal y As String) As Integer
        If x(0) >= "0"c AndAlso x(0) <= "9"c AndAlso y(0) >= "0"c AndAlso y(0) <= "9"c Then
            Dim tx = x.TrimStart("0"c)
            Dim ty = y.TrimStart("0"c)

            Dim result = tx.Length.CompareTo(ty.Length)

            If result <> 0 Then Return result

            result = tx.CompareTo(ty)

            If result <> 0 Then Return result
        End If

        Return String.Compare(x, y)
    End Function

    Public Function Compare(ByVal x As String?, ByVal y As String?) As Integer Implements IComparer(Of String).Compare
        If ReferenceEquals(x, y) Then Return 0
        If x Is Nothing Then Return -1
        If y Is Nothing Then Return +1

        Dim itemsX = Regex.Split(x, "([0-9]+)").Where(Function(item) Not String.IsNullOrEmpty(item)).ToList()

        Dim itemsY = Regex.Split(y, "([0-9]+)").Where(Function(item) Not String.IsNullOrEmpty(item)).ToList()

        Dim i = 0

        While i < Math.Min(itemsX.Count, itemsY.Count)
            Dim result = CompareChunks(itemsX(i), itemsY(i))

            If result <> 0 Then Return result
            Threading.Interlocked.Increment(i)
        End While

        Return itemsX.Count.CompareTo(itemsY.Count)
    End Function
End Class

Public Class Program
    Public Shared Sub Main()
        Dim demo = New String() {"B01 002", "B01 0010", "01", "B01 001", "B10 001", "B01 01", "1", "B1 001", "B02 001", "A1"}

        Array.Sort(demo, New NaturalComparer())

        Console.WriteLine(String.Join(Environment.NewLine, demo))
    End Sub
End Class

Error #1:

Error BC30401
'Compare' cannot implement 'Compare' because there is no matching function on interface 'IComparer(Of String)'. ConsoleApp4 C:\Users\RamAnjana\source\repos\ConsoleApp4\Program.vb 26 N/A\

Error #2:

Error BC30149
Class 'NaturalComparer' must implement 'Function Compare(x As String, y As String) As Integer' for interface 'IComparer(Of String)'.ConsoleApp4 C:\Users\RamAnjana\source\repos\ConsoleApp4\Program.vb

Error #3:

Error BC33101
Type 'String' must be a value type or a type argument constrained to 'Structure' in order to be used with 'Nullable' or nullable modifier '?'. ConsoleApp4 C:\Users\RamAnjana\source\repos\ConsoleApp4\Program.vb

Error #4:

Error BC33101
Type 'String' must be a value type or a type argument constrained to 'Structure' in order to be used with 'Nullable' or nullable modifier '?'.
ConsoleApp4 C:\Users\RamAnjana\source\repos\ConsoleApp4\Program.vb

I tried to change it in many ways but still got errors.


Solution

  • Remove ? from String, it seems that nullable reference types are not supported in VB.NET:

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