我有幾個實現IFoo接口的類。我需要在表中顯示這些類的對象列表,我希望能夠通過表中的任意列進行排序。所以,該表的數據源是List<IFoo>
。對接口對象列表進行排序
我遇到的問題是在列表中使用對象的IComparable
或IComparer
的標準方式需要靜態方法,但靜態方法不允許在接口中使用。所以,這個問題歸結爲:如何排序List<IFoo>
?
我有幾個實現IFoo接口的類。我需要在表中顯示這些類的對象列表,我希望能夠通過表中的任意列進行排序。所以,該表的數據源是List<IFoo>
。對接口對象列表進行排序
我遇到的問題是在列表中使用對象的IComparable
或IComparer
的標準方式需要靜態方法,但靜態方法不允許在接口中使用。所以,這個問題歸結爲:如何排序List<IFoo>
?
IComparable的
我不知道是什麼給了你,你需要使用一個靜態方法的想法,但它是不正確的。
你就可以把它迫使所有的IFoo
實施者實施IComparable<IFoo>
到IFoo
:
interface IFoo : IComparable<IFoo>
{
int Value { get; set; } // for example's sake
}
class SomeFoo : IFoo
{
public int Value { get; set; }
public int CompareTo(IFoo other)
{
// implement your custom comparison here...
return Value.CompareTo(other.Value); // e.g.
}
}
然後簡單排序你List<IFoo>
像這樣:
list.Sort();
通過任意列排序
你最初說喲你想按照IFoo對象表中的任意列進行排序。這更復雜;您需要能夠通過任何一個公共屬性對對象列表進行排序,因此上述基本的IComparable<IFoo>
實現不會削減它。
的解決方案是創建一個PropertyComparer<T>
類,它實現IComparer<T>
,並將被的T
任何屬性進行排序。你可以專門爲IFoo
編寫它,但是在某個時候,每個開發者往往都會遇到這個問題,並最終編寫一個通用屬性比較器來嘗試對任何類型進行排序。因此,你可以谷歌「C#屬性比較」,你一定會得到幾個命中。這裏有一個簡單的一個:
http://www.codeproject.com/Articles/16200/Simple-PropertyComparer
我不知道你正在運行的問題,因爲到我剛跑了一個快速測試,並可能進行排序的IFoo的列表。看下面我是如何做到這一點的。如果這不符合你的需要,你可以提供更多的細節嗎?
var fooList = new List<IFoo>{new testFoo{key=3}, new testFoo{key=1}};
fooList.Sort(
delegate(IFoo obj1, IFoo obj2){return obj1.key.CompareTo(obj2.key);});
接口和混凝土
public interface IFoo
{
int key{get;set;}
}
public class testFoo:IFoo
{
public int key {get;set;}
}
如果使用C#3/4,則可以使用lambda表達式..
這個例子展示瞭如何可以通過的不同特性進行排序IFoo的接口:
void Main()
{
List<IFoo> foos = new List<IFoo>
{
new Bar2{ Name = "Pqr", Price = 789.15m, SomeNumber = 3 },
new Bar2{ Name = "Jkl", Price = 444.25m, SomeNumber = 1 },
new Bar1{ Name = "Def", Price = 222.5m, SomeDate = DateTime.Now },
new Bar1{ Name = "Ghi", Price = 111.1m, SomeDate = DateTime.Now },
new Bar1{ Name = "Abc", Price = 123.45m, SomeDate = DateTime.Now },
new Bar2{ Name = "Mno", Price = 564.33m, SomeNumber = 2 }
};
foos.Sort((x,y) => x.Name.CompareTo(y.Name));
foreach(IFoo foo in foos)
{
Console.WriteLine(foo.Name);
}
foos.Sort((x,y) => x.Price.CompareTo(y.Price));
foreach(IFoo foo in foos)
{
Console.WriteLine(foo.Price);
}
}
interface IFoo
{
string Name { get; set; }
decimal Price { get; set; }
}
class Bar1 : IFoo
{
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime SomeDate { get; set; }
}
class Bar2 : IFoo
{
public string Name { get; set; }
public decimal Price { get; set; }
public int SomeNumber { get; set; }
}
輸出:
Abc
Def
Ghi
Jkl
Mno
Pqr
111.1
222.5
333.33
444.25
555.45
666.15
這很好,因爲按任意列進行排序是一項要求。它也很好地封裝了這種類型,這使得代碼更具可讀性。擁有通用屬性比較器對於其他用途也非常有用。 – 2012-03-02 17:10:07