我有几个实现接口的类,IFoo。我需要在表格中显示这些类的对象列表,我希望能够按表格中的任意列进行排序。因此,表的数据源是List<IFoo>
.
我遇到的问题是实现IComparable
或IComparer
用于列表中的对象的标准方式需要静态方法,但接口中不允许使用静态方法。所以,问题归结为:如何排序 a List<IFoo>
?
我有几个实现接口的类,IFoo。我需要在表格中显示这些类的对象列表,我希望能够按表格中的任意列进行排序。因此,表的数据源是List<IFoo>
.
我遇到的问题是实现IComparable
或IComparer
用于列表中的对象的标准方式需要静态方法,但接口中不允许使用静态方法。所以,问题归结为:如何排序 a List<IFoo>
?
可比的
我不知道是什么让您认为您需要使用静态方法,但这是不正确的。
您可以通过将其添加到以下位置来强制所有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
. 因此,您可以在 Google 上搜索“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