2

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.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Ram
  • 131
  • 8
  • 3
    Are there nullable reference types in VB.NET? If not then `String?` should be `String` – Adriano Repetti Apr 17 '23 at 15:53
  • The help for the [BC33101](https://learn.microsoft.com/en-us/dotnet/visual-basic/misc/bc33101) error. – Ralf Apr 17 '23 at 16:07
  • @AdrianoRepetti, It's working. Thanks for your valuable suggestion and time. – Ram Apr 17 '23 at 16:09
  • I think (it's been a while since I worked in VB), that you would have found a solution if you had approached this top down. Had you started with `Public NotInheritable Class NaturalComparer Implements IComparer(Of String)` (and `End Class`), you would have been given the chance to get an empty implementation of the methods of `IComparer(Of String)`. Those pesky `?` wouldn't have popped up then. – Flydog57 Apr 17 '23 at 17:05

1 Answers1

3

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
Guru Stron
  • 102,774
  • 10
  • 95
  • 132