Передайте лямбда-выражение вместо iComparator в VB.Net - PullRequest
0 голосов
/ 11 мая 2019

У меня есть следующее выражение C #

var orderedMatches = matches.OrderBy((t1, t2) => t1.Item1 - t2.Item1).ToList();

И я пытаюсь перевести на VB с Option Strict On, большинство переводчиков выдают что-то вроде ниже

Dim orderedMatches As List(Of Tuple(Of Integer, String)) = matches.OrderBy(Function(t1 As Tuple(Of Integer, String), t2 As Object) t1.Item1 - t2.Item1).ToList()

Или чуть ниже и ниодин компилируется.

Dim orderedMatches As List(Of Tuple(Of Integer, String)) = matches.OrderBy(Function(t1, t2) t1.Item1 - t2.Item1).ToList()

Я попробовал несколько конвертеров, а также установил Option Strict Off и установил T1 и T2 на Object.Обычная ошибка:

BC36532 Nested function does not have the same signature as delegate 'Func(Of Tuple(Of Integer, String), Object)'

OrderBy определяется как

Public Shared Function OrderBy(Of TSource, TKey)(source As IEnumerable(Of TSource), keySelector As Func(Of TSource, TKey)) As IOrderedEnumerable(Of TSource)

или

Public Shared Function OrderBy(Of TSource, TKey)(source As IEnumerable(Of TSource), keySelector As Func(Of TSource, TKey), comparer As IComparer(Of TKey)) As IOrderedEnumerable(Of TSource)

Мне нужно кодировать для компиляции с ошибками, желательно с Option Strict On

Ответы [ 2 ]

0 голосов
/ 29 мая 2019

Синтаксис в VB.NET выглядит следующим образом:

Dim orderedMatches = matches.OrderBy(Function(x, y) x.Item1 - y.Item1).ToList()

, хотя ваша логика сортировки содержит ошибки и в моем примере происходит сбой с Int32.MinValues ​​и Int32.MaxValues ​​из-за арифметических переполнений.Надежная реализация может выглядеть следующим образом:

Dim orderedMatches = matches.OrderBy(Function(x, y)
                                            If (x.Item1 < y.Item1) Then Return -1
                                            If (y.Item1 < x.Item1) Then Return 1
                                            Return 0
                                        End Function).ToList()

Оба приведенных выше примера работают только в том случае, если где-то определен и импортирован метод расширения OrderBy (в C # и VB.NET), который работает следующим образом:

<Extension>
Public Module BubbleSortLambda

    <Extension>
    Public Function OrderBy(Of T)(collection As IEnumerable(Of T), logic As Func(Of T, T, Int32)) As IEnumerable(Of T)
        If (collection Is Nothing) Then Throw New NullReferenceException() 'To simulate instance method behavior
        If (logic Is Nothing) Then logic = Function(x, y) 0
        Dim myComparer As New GenericComparer(Of T)(logic)
        Dim myArray As T() = collection.ToArray()
        Array.Sort(myArray, myComparer)
        Return myArray
    End Function

    Private Class GenericComparer(Of T)
        Implements IComparer(Of T)

        'Private Fields
        Private ReadOnly _SortLogic As Func(Of T, T, Int32)

        'Constructors

        Public Sub New(sortLogic As Func(Of T, T, Int32))
            If (sortLogic Is Nothing) Then Throw New ArgumentNullException(NameOf(sortLogic))
            _SortLogic = sortLogic
        End Sub

        'Public Methods
        Public Function Compare(x As T, y As T) As Int32 Implements IComparer(Of T).Compare
            'Handle null
            If (x Is Nothing) Then
                If (y Is Nothing) Then Return 0
                Return -1
            End If
            If (y Is Nothing) Then Return 1
            'Invoke logic
            Return _SortLogic(x, y)
        End Function

    End Class

End Module
0 голосов
/ 28 мая 2019
'Hint: Would be usually done in the project settings...
Option Explicit On
Option Strict On
Option Infer On

Module StartUp

    Public Sub Main(args As String())
        Dim matches = GenerateData()
        Dim orderedMatches = (From e In matches Order By e.Item1).ToList()
        orderedMatches.ForEach(Sub(x) Console.Out.WriteLine(x))
        Console.Read()
    End Sub

    Private Iterator Function GenerateData() As IEnumerable(Of Tuple(Of Int32, String))
        Yield Tuple.Create(100, "Hundred")
        Yield Tuple.Create(1, "One")
        Yield Tuple.Create(Int32.MinValue, "MinValue")
        Yield Tuple.Create(Int32.MaxValue, "MaxValue")
        Yield Tuple.Create(0, "Zero")
    End Function

End Module
...