2

我有一个MyObjectmyObjects as List(Of MyObject)和一个Comparison(Of MyObject)使用大量比较函数(ByA、ByB、ByC 等)的委托 à la:

Shared Function CompareMyObjectsByName(x As MyObject, y As MyObject) As Integer
    Return x.Name.CompareTo(y.Name)
End Function

现在我可以使用

myObjects.Sort(AddressOf CompareMyObjectsByName)

我如何使用它来排序DescendingAscending

啦啦

myObjects.Sort(AddressOf CompareMyObjectsByName, ascending)

PS。不要说我应该写两个不同的比较器......

编辑@Jon Skeet

  ''' <summary>
  ''' Sorts a list ascensing or descending using a comparison delegate.
  ''' </summary>
  <System.Runtime.CompilerServices.Extension()> _
  Public Sub Sort(Of T)(ByVal list As List(Of T), ByVal comparison As Comparison(Of T), ByVal descending As Boolean)

    If Not descending Then
      list.Sort(comparison)
    Else
      list.Sort(???)
    End If

  End Sub
4

2 回答 2

4

最简单的方法是创建一个ReverseComparer(Of T)可以从现有构造IComparer(Of T)并反转比较的方法。(只需调用与参数顺序相反的现有比较 -不要否定结果;这对 . 失败。)如果您有兴趣,Int32.MinValue我已经在MiscUtil中有这样的 C# 类。

然后,您只需要通过传入升序比较器或通过从升序比较器创建反向比较器来进行排序。

编辑:看起来我并没有说清楚,这是我的意思的扩展方法 - 用 C# 编写,但应该很容易将其转换为 VB:

public static void Sort<T>(this List<T> list,
                           IComparer<T> comparer,
                           bool ascending)
{
    if (!ascending)
    {
        comparer = new ReverseComparer<T>(comparer);
    }
    list.Sort(comparer);
}

或对于Comparison<T>

public static void Sort<T>(this List<T> list,
                           Comparison<T> comparison,
                           bool ascending)
{
    if (!ascending)
    {
        // Avoid capturing the variable we're modifying!
        Comparison<T> originalComparison = comparison;
        comparison = (x, y) => originalComparison(y, x);
    }
    list.Sort(comparison);
}

当然,我通常会使用OrderByandOrderByDescending除非您真的需要修改原始列表...

编辑:进一步说明:正如 Konrad 所建议的,为了清楚起见,您可能需要一个带有成员的枚举,AscendingDescending不是一个bool标志。

于 2011-07-05T15:07:06.423 回答
1

接受 Jon 的建议,但使其与 lambda 表达式一起使用:

myObjects.Sort(Function (a, b) CompareMyObjectsByName(b, a))

– 无需为每个比较逻辑创建新方法;只需在具有反向参数的 lambda 中调用相应的比较方法。

于 2011-07-05T15:13:08.217 回答