在 VB.Net 中传递 lambda 表达式代替 iComparator

Pass a lambda expression in place of iComparator in VB.Net

我有以下 C# 表达式

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

我正在尝试使用 Option Strict On 翻译成 VB,大多数译员会生成如下内容

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

'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

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