对接口对象列表进行排序

时间:2012-02-29 15:50:01

标签: c# .net sorting icomparable

我有几个实现接口的类,IFoo。我需要在表中显示这些类的对象列表,我希望能够按表中的任意列进行排序。因此,该表的数据源为List<IFoo>

我遇到的问题是,对于列表中使用的对象实现IComparableIComparer的标准方法需要静态方法,但接口中不允许使用静态方法。所以,问题归结为:如何对List<IFoo>进行排序?

3 个答案:

答案 0 :(得分:8)

<强> 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>的{​​{1}}类,并按 IComparer<T>的任何属性进行排序。你可以专门为T编写它,但在某些时候,每个开发人员都会遇到这个问题并最终编写一个通用的属性比较器,它将尝试对任何类型进行排序。因此,你可以谷歌“c#属性比较”,你肯定会得到几个点击。这是一个简单的:

http://www.codeproject.com/Articles/16200/Simple-PropertyComparer

答案 1 :(得分:3)

我不确定你遇到了什么问题,因为我刚刚运行了一个快速测试,可以对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;}
}

答案 2 :(得分:0)

如果您使用的是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