开发者

Dictionary.ContainsKey misbehave c#

I've got a class Column

public class Column
{
    public int Id { get; private set; }
    public string Name { get; private set; }
    public EPersonalCharacteristicType Type { get; private set; }
    public Column MainColumn { get; private set; }
}

and I've got the following field in another class

Dictionary<Column, string> dictionary

In the middle of execution I get a strange behavior of this dictionary. When I typed

dictionary.ContainsKey(dictionary.Keys.ToList()[1])

I got false.

How on Earth can it be?

UPDATED

my Column class has GetHashCode or Equals Functions. Here are the implementations of them:

public bool Equals(Column other)
{
    if (ReferenceEquals(null, other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return other.Id == Id && Equals(other.Name, Name) && Equals(other.Type, Type) && Equals(other.MainColumn, MainColumn) && Equals(other.childColumns, childColumns);
}

public override bool Equals(object obj)
{
    if (ReferenceEquals(null, obj)) return false;
    if (ReferenceEquals(this, obj)) return true;
    if (obj.GetType() != typeof (Column)) return false;
    return Equals((Column) obj);
}

public override int GetHashCode()
{
    unchecked
    {
        int result = Id;
   开发者_如何学Go     result = (result*397) ^ (Name != null ? Name.GetHashCode() : 0);
        result = (result*397) ^ Type.GetHashCode();
        result = (result*397) ^ (MainColumn != null ? MainColumn.GetHashCode() : 0);
        result = (result*397) ^ (childColumns != null ? childColumns.GetHashCode() : 0);
        return result;
    }
}

public static bool operator ==(Column left, Column right)
{
    return Equals(left, right);
}

public static bool operator !=(Column left, Column right)
{
    return !Equals(left, right);
}


This is not a general problem but something specific to your code.

UPDATE:
The hash code of the key of a dictionary must not change. This is not the case with your Column class, because as soon as any of its properties are changed, the hash code changes, too.
Documentation:

As long as an object is used as a key in the Dictionary, it must not change in any way that affects its hash value.

The background of this is the following: The dictionary retrieves and stores the hash code of the key at the time it is added. If the hash code of the key changed after that, it is different to the stored hash code and the object will not be seen as equal to the originally inserted key.


If Dictionary<Column, string> is right, then I would guess it's because the type Column is not compatible with how Dictionary<TKey, TValue> checks equality - which is based on comparisons through GetHashCode and Equals - and my guess is that the Column type does not implement these.

Change the key type of the dictionary to something more suited to comparisons and equality. Ideally use a string derived from the column's name.

Update

Based on your code update, my guess is that something about the column has changed since it went into the dictionary that causes its 'live' hash code to change from what it was when it was first added to the Dictionary - so that could be any change in Id, Name, Type, MainColumn or ChildColumns that causes their HashCodes to change.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜