好的,我有一个类似于下面代码的场景,我有一个实现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());
}
答案 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();