Câu trả lời được chấp nhận bởi @DavidMills là khá tốt, nhưng tôi nghĩ nó có thể được cải thiện. Đối với một, không cần xác định ComparisonComparer<T>
lớp khi khung công tác đã bao gồm một phương thức tĩnh Comparer<T>.Create(Comparison<T>)
. Phương pháp này có thể được sử dụng để tạo một IComparison
cách nhanh chóng.
Ngoài ra, nó phôi IList<T>
để IList
mà có khả năng gây nguy hiểm. Trong hầu hết các trường hợp mà tôi đã thấy, nông cụ List<T>
nào IList
được sử dụng ở hậu trường để triển khaiIList<T>
, nhưng điều này không được đảm bảo và có thể dẫn đến mã giòn.
Cuối cùng, List<T>.Sort()
phương thức nạp chồng có 4 chữ ký và chỉ 2 trong số chúng được thực hiện.
List<T>.Sort()
List<T>.Sort(Comparison<T>)
List<T>.Sort(IComparer<T>)
List<T>.Sort(Int32, Int32, IComparer<T>)
Lớp dưới đây thực hiện tất cả 4 List<T>.Sort()
chữ ký cho IList<T>
giao diện:
using System;
using System.Collections.Generic;
public static class IListExtensions
{
public static void Sort<T>(this IList<T> list)
{
if (list is List<T>)
{
((List<T>)list).Sort();
}
else
{
List<T> copy = new List<T>(list);
copy.Sort();
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, Comparison<T> comparison)
{
if (list is List<T>)
{
((List<T>)list).Sort(comparison);
}
else
{
List<T> copy = new List<T>(list);
copy.Sort(comparison);
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, IComparer<T> comparer)
{
if (list is List<T>)
{
((List<T>)list).Sort(comparer);
}
else
{
List<T> copy = new List<T>(list);
copy.Sort(comparer);
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, int index, int count,
IComparer<T> comparer)
{
if (list is List<T>)
{
((List<T>)list).Sort(index, count, comparer);
}
else
{
List<T> range = new List<T>(count);
for (int i = 0; i < count; i++)
{
range.Add(list[index + i]);
}
range.Sort(comparer);
Copy(range, 0, list, index, count);
}
}
private static void Copy<T>(IList<T> sourceList, int sourceIndex,
IList<T> destinationList, int destinationIndex, int count)
{
for (int i = 0; i < count; i++)
{
destinationList[destinationIndex + i] = sourceList[sourceIndex + i];
}
}
}
Sử dụng:
class Foo
{
public int Bar;
public Foo(int bar) { this.Bar = bar; }
}
void TestSort()
{
IList<int> ints = new List<int>() { 1, 4, 5, 3, 2 };
IList<Foo> foos = new List<Foo>()
{
new Foo(1),
new Foo(4),
new Foo(5),
new Foo(3),
new Foo(2),
};
ints.Sort();
foos.Sort((x, y) => Comparer<int>.Default.Compare(x.Bar, y.Bar));
}
Ý tưởng ở đây là tận dụng chức năng của phần mềm bên dưới List<T>
để xử lý việc sắp xếp bất cứ khi nào có thể. Một lần nữa, hầu hết các IList<T>
triển khai mà tôi đã thấy đều sử dụng điều này. Trong trường hợp khi tập hợp cơ bản là một kiểu khác, hãy dự phòng để tạo một phiên bản mới List<T>
với các phần tử từ danh sách đầu vào, sử dụng nó để thực hiện việc sắp xếp, sau đó sao chép kết quả trở lại danh sách đầu vào. Điều này sẽ hoạt động ngay cả khi danh sách đầu vào không triển khai IList
giao diện.