Problem with CompareTo

I am trying to implement a sorted list. I created a class that I want to keep in the list, but for some reason, when I try to start sorting the sort method, I get an exception. It seems like something behind the scenes is passing in a null reference to the CompareTo method that I implemented.

Here is what I find relevant code.

A data object is defined as follows:

 namespace PrioritisedRequestQueue { public class XactTask : IComparable<XactTask> { public int priority; public DateTime submitted; public string name; public XactTask( int priority, DateTime submitted, string name) { this.priority = priority; this.submitted = submitted; this.name = name; } public int CompareTo(XactTask rhs ) { //EXCEPTION OCCURS HERE AFTER A NULL RHS HAS BEEN PASSED IN** Console.WriteLine("comparing " + rhs.priority+"to "+this.priority); if (rhs.priority <= this.priority) { Console.WriteLine("Entered first if"); Console.WriteLine("comparing " + rhs.submitted + "to " + this.submitted); if (rhs.submitted <= this.submitted) { Console.WriteLine("Entered second if"); return 1; } else { return -1; } } else { Console.WriteLine("In else"); return -1; } } } } 

And the class for storing the list is defined as follows:

 namespace PrioritisedRequestQueue { public class Class1 { public List<XactTask> tasks; public Class1() { tasks = new List<XactTask>(); } public void sort() { tasks.Sort(); } public void add(XactTask task) { tasks.Add(task); } } } 

Here is the program I use for testing:

 PrioritisedRequestQueue.Class1 tester = new PrioritisedRequestQueue.Class1(); tester.add(new PrioritisedRequestQueue.XactTask(1, DateTime.Now, "test1")); tester.add(new PrioritisedRequestQueue.XactTask(1, DateTime.Now, "test2")); Console.WriteLine(tester.tasks[0].name); Console.WriteLine(tester.tasks[1].name); tester.tasks.Sort(); 

Test program output:

  comparing 1to 1 Entered first if comparing 16/05/2011 14:41:57to 16/05/2011 14:41:57 Entered second if comparing 1to 1 Entered first if comparing 16/05/2011 14:41:57to 16/05/2011 14:41:57 Entered second if comparing 1to 1 Entered first if comparing 16/05/2011 14:41:57to 16/05/2011 14:41:57 Entered second if comparing 1to 1 Entered first if comparing 16/05/2011 14:41:57to 16/05/2011 14:41:57 Entered second if 

Then it seems to pass the null rhs object to the comparison method, and I get a NullReferenceException when it tries to access the rhs priority.

Can you tell me why this is happening and what should I do to solve this problem?

Please let me know if you need more information.

+4
source share
1 answer

When I run my code, I get an InvalidOperationException because CompareTo not executing correctly.

The CompareTo implementation should return 0 if rhs matches this (i.e., this object and the compared object are equal). It also must not fail if rhs == null , but must order null sequential manner; this is usually done by returning 1 to sort null before all valid objects.

The documentation for IComparable.CompareTo contains the following rules that must be followed for Sort to work correctly:

  • A.CompareTo(A) is required to return zero.

  • If A.CompareTo(B) returns zero, then B.CompareTo(A) is required to return zero.

  • If A.CompareTo(B) returns zero and B.CompareTo(C) returns zero, then A.CompareTo(C) needs to return zero.

  • If A.CompareTo(B) returns a value other than zero, then B.CompareTo(A) needs to return the value of the opposite sign.

  • If A.CompareTo(B) returns a value of x which is not zero, and B.CompareTo(C) returns y of the same sign as x, then A.CompareTo(C) needs to return a value of the same sign as x and y.

To fix the problem, make sure your CompareTo implementation returns 0 when priority == rhs.priority && submitted == rhs.submitted .

+9
source

All Articles