首页 > 解决方案 > 字典不使用类的比较方法

问题描述

几天前,我为我写的一个类问了一个关于 C# 中字典实现的问题。我有一本字典,其中包含 class 的键和 class 的IntervalLine2D。我更新的间隔实现如下所示:

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}]";
}

因此,如果我创建一个键是Interval对象的字典,我认为我的CompareTo方法将涵盖两个间隔具有相同起点和终点的情况。然而,这种情况并非如此。

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

为什么默认比较器CompareTo在执行期间不跳到我的方法中?

标签: c#dictionary

解决方案


要将复杂值用作字典键,您需要专门实现GetHashCode()Equals()CompareTo与此用例无关。


推荐阅读