I am trying to implement a sorted list. I have created the class I want to have stored in the list, but for some reason when I try and run the sort the sort method I get an exception thrown. It appears something behind the scenes is passing in a null
reference into the CompareTo
method I have implemented.
Here’s what I believe to be relevant code.
Data object is defined like this:
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 to hold the list is defined like this:
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 to do the 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();
The output of the test program is:
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 a null
rhs object into the compare method and I get a NullReferenceException
when it tries to access the priority of rhs.
Can you tell me why this is happening and what I have to do to address this?
Please let me know if you need any more information.
When I run your code, I get an InvalidOperationException
because CompareTo
is not implemented correctly.
Your CompareTo
implementation must return 0
if rhs
is the same as this
(i.e., this object and the object being compared are equal). It also should not fail if rhs == null
, but should order null
in a consistent way; this is typically done by always returning 1
to sort null
before all valid objects.
The documentation for IComparable.CompareTo lists the following rules, which must be followed in order for Sort to function 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)
is required to return
zero.
If A.CompareTo(B)
returns a value
other than zero, then B.CompareTo(A)
is required to return a value of the
opposite sign.
If A.CompareTo(B)
returns a value x
that is not equal to zero, and
B.CompareTo(C)
returns a value y of
the same sign as x, then
A.CompareTo(C)
is required to return
a value of the same sign as x and y.
To fix the problem, ensure that your implementation of CompareTo
returns 0 when priority == rhs.priority && submitted == rhs.submitted
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With