我有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
答案 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);
}
当然,我通常会使用OrderBy
和OrderByDescending
,除非真的需要修改原始列表......
编辑:进一步说明:根据Konrad的建议,您可能需要一个包含成员Ascending
和Descending
而不是bool
标记的枚举,仅为了清晰起见。
答案 1 :(得分:1)
采用Jon的建议,但使其与lambda表达式一起使用:
myObjects.Sort(Function (a, b) CompareMyObjectsByName(b, a))
- 无需为每个比较逻辑创建新方法;只需在反向参数的lambda中调用相应的比较方法。