1

我正在获取字典中的第一个键并将其与查找值进行比较。它们是相同的,但是当我尝试从字典中访问密钥时,我得到KeyNotFoundException

    public void Draw(Graphics graphics, Shape shape)
    {
        foreach (var line in shape.Lines)
        {
            var tuple = shape.LinesToNurmalDictionary.Keys.First();

            bool equals = tuple == line;
            bool referenceEquals = ReferenceEquals(tuple, line);

            var invisible = shape.LinesToNurmalDictionary[line].All(x => x.Z < 0);

我该如何解决?

图片

补充:字典是

Dictionary<Tuple<ShapePoint, ShapePoint>, List<ShapePoint>> LinesToNurmalDictionary;

其中 ShapePoint 是一个类

所以我通过使用我自己的类而不是元组来“​​解决”我的问题,但实际上问题仍然没有得到回应:

public class Line
{
    public ShapePoint A { get; set; }
    public ShapePoint B { get; set; }

    public List<ShapePoint> Normals { get; set; }

    public Line(ShapePoint a, ShapePoint b)
    {
        A = a;
        B = b;
        Normals = new List<ShapePoint>();
    }

    private sealed class DefaultEqualityComparer : IEqualityComparer<Line>
    {
        public bool Equals(Line x, Line y)
        {
            if (ReferenceEquals(x, y))
                return true;
            if (ReferenceEquals(x, null))
                return false;
            if (ReferenceEquals(y, null))
                return false;
            if (x.GetType() != y.GetType())
                return false;
            return Equals(x.A, y.A) && Equals(x.B, y.B);
        }

        public int GetHashCode(Line obj)
        {
            unchecked
            {
                return ((obj.A != null ? obj.A.GetHashCode() : 0)*397) ^ (obj.B != null ? obj.B.GetHashCode() : 0);
            }
        }
    }

    private static readonly IEqualityComparer<Line> DefaultComparerInstance = new DefaultEqualityComparer();

    public static IEqualityComparer<Line> DefaultComparer
    {
        get
        {
            return DefaultComparerInstance;
        }
    }
}
4

1 回答 1

2

正如 tia 在评论中已经说过的那样,发生这种情况是因为首先将一个条目添加到Dictionary<,>键的哈希码(这里是Tuple<ShapePoint, ShapePoint>)具有一些值的地方,该值是“保存”并由Dictionary<,>. 之后,密钥对象以更改其哈希码的方式“变异”(修改)。这导致Dictionary<,>处于腐败状态。

因此,当之后搜索密钥时,它没有找到。它的“新”哈希码与Dictionary<,>认为该密钥具有的哈希不同。

不要以更改其哈希码的方式修改可能是 a 中的键Dictionary<,>(或 a 等的成员)的对象。HashSet<>


这是一个说明的例子。类型:

class Changeable
{
    public int Prop { get; set; }

    public override int GetHashCode()
    {
        return Prop;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Changeable);
    }
    public bool Equals(Changeable other)
    {
        if (other == null)
            return false;

        return GetType() == other.GetType() && Prop == other.Prop;
    }
}

给出相同问题的代码:

var onlyInstance = new Changeable();

var dict = new Dictionary<Changeable, string>();

onlyInstance.Prop = 1;
dict.Add(onlyInstance, "what-ever");

onlyInstance.Prop = 2;
string restoredValue = dict[onlyInstance]; // throws!
于 2013-10-06T15:38:17.330 回答