【问题标题】:Sort a list of interface objects对接口对象列表进行排序
【发布时间】:2012-03-19 02:57:12
【问题描述】:

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

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

【问题讨论】:

    标签: c# .net sorting icomparable


    【解决方案1】:

    IComparable

    我不知道是什么让您认为您需要使用静态方法,但这是不正确的。

    您可以通过将IComparable<IFoo> 添加到IFoo 来强制所有IFoo 实现者实现IComparable<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&lt;IFoo&gt; 进行排序:

    list.Sort();
    

    按任意列排序

    您最初声明要按 IFoo 对象表中的任意列进行排序。这更复杂;您需要能够按对象的任何一个公共属性对对象列表进行排序,因此上面的基本IComparable&lt;IFoo&gt; 实现不会削减它。

    解决方案是创建一个实现IComparer&lt;T&gt;PropertyComparer&lt;T&gt; 类,并将按T 的任何属性进行排序。您可以专门为IFoo 编写它,但在某些时候,每个开发人员都会遇到这个问题并最终编写一个通用属性比较器来尝试对任何类型进行排序。因此,您可以在 Google 上搜索“c# 属性比较器”,并且一定会获得一些点击率。这是一个简单的:

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

    【讨论】:

    • 这很好用,因为按任意列排序是必需的。它还很好地封装了排序,这使得代码更具可读性。拥有一个通用的属性比较器对于其他用途也非常有用。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-20
        • 1970-01-01
        • 2016-11-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多