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 phải xác định lớp ComparisonComparer<T>
khi khuôn khổ đã 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 ra IComparison
khi đang di chuyển.
Ngoài ra, nó hoạt động IList<T>
đến IList
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, List<T>
thực hiện IList
được sử dụng phía sau hậu trường để thực hiện IList<T>
, nhưng điều này không được bảo đảm và có thể dẫn đến mã giòn.
Cuối cùng, phương thức quá tải List<T>.Sort()
có 4 chữ ký và chỉ 2 chữ ký được triển khai.
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 giao diện IList<T>
:
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(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];
}
}
}
Cách 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 các chức năng của cơ bản List<T>
để xử lý sắp xếp bất cứ khi nào có thể. Một lần nữa, hầu hết các triển khai IList<T>
mà tôi đã thấy sử dụng. Trong trường hợp bộ sưu tập cơ bản là một kiểu khác, dự phòng để tạo một thể hiện mới là List<T>
với các phần tử từ danh sách đầu vào, sử dụng nó để thực hiện 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ẽ làm việc ngay cả khi danh sách đầu vào không thực hiện giao diện IList
.
Tại sao bạn sẽ trả lại một IList ngay từ đầu? Từ một dịch vụ WCF? – DaeMoohn