如何使用List.Sort和Comparison(of T)对Descending / Ascending进行排序?

时间:2011-07-05 15:04:16

标签: .net vb.net sorting icomparer

我有MyObject; myObjects 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)

我如何使用它来排序降序升序

àla

myObjects.Sort(AddressOf CompareMyObjectsByName, ascending)

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

EDIT @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

2 个答案:

答案 0 :(得分: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);
}

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

编辑:进一步说明:根据Konrad的建议,您可能需要一个包含成员AscendingDescending而不是bool标记的枚举,仅为了清晰起见。

答案 1 :(得分:1)

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

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

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