Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I have a problem with IComparable and the collection sort method

Okay so I have a scenario similar to the below code, I have a parent class that implements IComparable and a child class.

class Parent : IComparable<Parent> 
class Child : Parent

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

Now the above works fine, i can compare two of the child objects to each other no problem

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

The above fails though with an InvalidOperationException. Can someone please explain why this sort isn't working when the child class does implement the IComparable interface, or at least it seems to me that it does.

Okay here is my CompareTo implementation for my actual parent class

 public int CompareTo(IDType other)
 {
       return this.Name.ToString().CompareTo(other.ToString());
 }
like image 629
CalvinR Avatar asked Feb 02 '09 16:02

CalvinR


People also ask

How to use IComparable interface in c#?

C# IComparable interface The IComparable is implemented by types whose values can be ordered or sorted. The interface requires the CompareTo method to be implemented. The implemented method is automatically called by methods such as Array. Sort and List.

What is the difference between IComparer and IComparable in C#?

IComparer compares two objects that it's given. IComparable is implemented by the object that is being compared, for the purpose of comparing with another one of itself.

How do you implement IComparable?

Implementing IComparable Interface requires:Adding a method CompareTo() which receives an object and returns an integer. The CompareTo() method depending on the comparison: returns 0, if the current instance's property is equal to the temporary variable's property.

When to use IComparer in c#?

The role of IComparer is to provide more comparison mechanisms. For example, you might want to provide ordering of your class on several fields or properties, ascending and descending order on the same field, or both. The IComparer. Compare method requires a tertiary comparison.


2 Answers

Your type implements IComparable<Parent> rather than IComparable<Child>. As the MSDN docs for Sort say, it will throw InvalidOperationException if "the default comparer Comparer(T).Default cannot find an implementation of the IComparable(T) generic interface or the IComparable interface for type T." And indeed it can't, where T is Child. If you try making it a List<Parent> you may well find it's fine.

EDIT: Alternatively (and preferably, IMO) implement IComparable<Child>. At the moment it's not at all clear that a child can sensibly be compared with another child. Implementing IComparable<Child> - even if that implementation just defers to the base implementation - advertises the comparability.

like image 101
Jon Skeet Avatar answered Sep 22 '22 06:09

Jon Skeet


I gave this a try and ran into the same error. My guess is that because you've got a List<Child> it's looking for someone that implements IComparable<Child>, not IComparable<Parent>.

If you change the collection to List<Parent>, things seem to work. Alternatively, have Child implement IComparable<Child> (and it can just delegate to Parent's implementation).

like image 25
AwesomeTown Avatar answered Sep 22 '22 06:09

AwesomeTown