我有IComparable和集合排序方法的问题

时间:2009-02-02 16:53:43

标签: c# .net generics inheritance

好的,我有一个类似于下面代码的场景,我有一个实现IComparable和子类的父类。

class Parent : IComparable<Parent> 
class Child : Parent

Child a = new Child();
Child b = new Child();
a.CompareTo(b);

现在上面工作正常,我可以比较两个子对象没有问题

List<Child> l = new List<Child>();
l.Add(b);
l.Add(a);
l.Sort();

但是上面因InvalidOperationException而失败。有人可以解释为什么当子类确实实现IComparable接口时这种类型无效,或者至少在我看来它确实如此。

好的,这是我的实际父类

的CompareTo实现
 public int CompareTo(IDType other)
 {
       return this.Name.ToString().CompareTo(other.ToString());
 }

3 个答案:

答案 0 :(得分:6)

您的类型实现IComparable<Parent>而不是IComparable<Child>。正如MSDN docs for Sort所说,如果“默认比较器Comparer(T).Default找不到IComparable(T)通用接口的实现或类型T的IComparable接口,它将抛出InvalidOperationException”事实上它不可能,T是Child。如果您尝试将其设为List<Parent>,您可能会发现它没问题。

编辑:或者(最好是IMO)实施IComparable<Child>。目前还不清楚孩子是否可以明智地与另一个孩子进行比较。实施IComparable<Child> - 即使该实施只是遵循基础实施 - 宣传可比性。

答案 1 :(得分:3)

我试了一下,遇到了同样的错误。我的猜测是,因为你有List<Child>它正在寻找实施IComparable<Child>的人,而不是IComparable<Parent>

如果您将集合更改为List<Parent>,那么事情似乎有效。或者,让Child实现IComparable<Child>(它可以只委托Parent的实现)。

答案 2 :(得分:3)

我的猜测是与协方差/逆变的东西有关。我之所以这样说,是因为这就像你说的那样失败了:

 public class Parent : IComparable<Parent>
    {
        public int Age { get; set; }


        public int CompareTo(Parent other)
        {

            return this.Age.CompareTo(other.Age);
        }

    }

    public class Child : Parent
    {
        public string Name { get; set; }
    }

但是,当我更改父级以实现非通用IComparable并执行此操作时,它起作用了:

    public class Parent : IComparable
    {
    public int Age { get; set; }


    public int CompareTo(object other)
    {
        Parent p = other as Parent;
        return this.Age.CompareTo(p.Age);
    }

}

    public class Child : Parent
    {
        public string Name { get; set; }
    }

Code I我用它测试了它:

    List<Child> c = new List<Child>();
    c.Add(new Child { Age = 10, Name = "Alex" });
    c.Add(new Child { Age = 6, Name = "Jack" });
    c.Add(new Child { Age = 15, Name = "Bob" });

    c.Sort();