RagnaRock
RagnaRock

Reputation: 2640

Dictionary is allowing me to insert duplicate keys

I've create some classes, so that I can have a dictionary with a pair as a key

public class RouteKey
{
    public Equip Equipment { get; set; }
    public Destiny Destiny { get; set; }

    public RouteKey() { }
    public RouteKey(Equip Equipment, Destiny Destiny) {
        this.Equipment = Equipment;
        this.Destiny = Destiny;
    }
}

public override bool Equals(object obj)
{
    if (obj == null) return false;

    if (this.GetType() != obj.GetType()) return false;

    RouteKey rk = (RouteKey)obj;

    // use this pattern to compare reference members
    if (!Object.Equals(Equipment, rk.Equipment)) return false;

    // use this pattern to compare value members
    if (!Destiny.Equals(rk.Destiny)) return false;

    return true;        
}

public class RouteValue
{
    public string Endpoint { get; set; }
    public bool Enabled { get; set; }

    public RouteValue() { }
    public RouteValue(string Endpoint, bool Enabled) {
        this.Endpoint = Endpoint;
        this.Enabled = Enabled;
    }
}

public Dictionary<RouteKey, RouteValue> Routes;

My problem is that I'm able to run this code without errors...

RouteKey rk1 = new RouteKey(Equip.SpaceShip, Destiny.sun);
RouteKey rk2 = new RouteKey(Equip.SpaceShip, Destiny.sun);
RouteKey rk3 = new RouteKey(Equip.Boat, Destiny.hell);

RouteValue rv1 = new RouteValue("rv1", true);
RouteValue rv2 = new RouteValue("rv2", false);
RouteValue rv3 = new RouteValue("rv3", true);

Routes.Add(rk1, rv1);
Routes.Add(rk3, rv3);
Routes.Add(rk2, rv2);

I've tried adding the equals method to the RouteKey class, but in debug I can see the code never passes by that method.

What can I do to have the dictionary to behave as expected?

Upvotes: 2

Views: 1627

Answers (3)

Oded
Oded

Reputation: 499002

You have only overridden Equals() in your RoutKey class.

You should also override GetHashCode() - this is what the Dictionary will be using for testing for equality.

When overriding Equals() and GetHashCode(), you should also consider overriding the == and != operators.

I suggest reading Guidelines for Overriding Equals() and Operator == (C# Programming Guide) on MSDN.

Upvotes: 3

Diego
Diego

Reputation: 1569

For the RouteKey class you need to override the GetHashCode() method:

http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx

Also you can check this SO question: When do we do GetHashCode() for a Dictionary?

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726579

Your RouteKey needs to override the GetHashCode() method in such a way that hash codes of equal RouteKey instances are also equal (but not necessarily the other way around).

Upvotes: 7

Related Questions