A few days ago, I asked a question about dictionary implementations in C# for a class I had written. I have a dictionary that has keys of class Interval
and values of class Line2D
. My updated implementation of interval looks like this:
public class Interval : ICloneable, IComparable, IComparable<Interval>, IComparable<double>
{
public Interval()
{
}
public Interval(Interval interval)
{
this.CopyFrom<Interval>(interval);
}
public Interval(double start, double end)
{
Start = start;
End = end;
}
// Properties
public double Start { get; set; } = double.NaN;
public double End { get; set; } = double.NaN;
public double Span => End - Start;
// Methods
public object Clone() => MemberwiseClone();
public int CompareTo(object obj)
{
if (obj is Interval iObj)
{
return CompareTo(iObj);
}
return 1;
}
public int CompareTo([AllowNull] Interval other)
{
if (Start == other.Start && End == other.End)
{
return 0;
}
else if (End <= other.Start)
{
return -1;
}
else if (other.End <= Start)
{
return 1;
}
else
{
throw new ArgumentException("Interval must not overlap with this one.", nameof(other));
}
// Old implementation
//if (Start < other.Start)
//{
// return -1;
//}
//else if (Start > other.Start)
//{
// return 1;
//}
//else
//{
// return 0;
//}
}
public int CompareTo([AllowNull] double other)
=> Contains(other) ? 0 : (other < Start ? 1 : -1);
public bool Contains(double x) => Start <= x && x <= End;
public override string ToString() => $"[{Start}, {End}]";
}
So if I create a dictionary where the keys are Interval
objects, I thought my CompareTo
methods would cover the situation where two intervals have the same starting point and end point. However, this is not the case.
var testDict = new Dictionary<Interval, int>();
var testInterval1 = new Interval(0, 1);
var testInterval2 = new Interval(testInterval1); // Should be identical
testDict[testInterval1] = 5;
var contains = testDict.ContainsKey(testInterval2); // This is false when it should be true;
testDict[testInterval2] = 10; // This shouldn't work but it does
Why doesn't the default comparer hop into my CompareTo
methods during execution?