通過@DavidMills接受的答案是相當不錯,但我認爲它可以改進。首先,當框架已經包含一個靜態方法Comparer<T>.Create(Comparison<T>)
時,沒有必要定義ComparisonComparer<T>
類。這種方法可用於即時創建IComparison
。
此外,它將IList<T>
轉換爲IList
,這有潛在危險。在我看到的大多數情況下,實現IList
的List<T>
在幕後用於實現IList<T>
,但這不能保證,並且會導致代碼變得脆弱。
最後,超載的List<T>.Sort()
方法有4個簽名,只有2個被實現。
List<T>.Sort()
List<T>.Sort(Comparison<T>)
List<T>.Sort(IComparer<T>)
List<T>.Sort(Int32, Int32, IComparer<T>)
以下類用於實現IList<T>
接口的所有4 List<T>.Sort()
簽名:
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];
}
}
}
用法:
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));
}
這裏的想法是利用底層List<T>
的功能來處理排序只要有可能。同樣,我見過的大多數IList<T>
實現都使用這個。在底層集合是不同類型的情況下,回退到使用輸入列表中的元素創建新實例List<T>
,使用它進行排序,然後將結果複製回輸入列表。即使輸入列表沒有實現接口IList
,這也可以工作。
爲什麼你會首先返回一個IList?從WCF服務? – DaeMoohn 2011-02-18 15:42:20