Question

I am currently trying to use the containskey method to check if a dictionary i have contains a certain key of a custom type. To do this i should override the gethashcode function, which i have, however the containskey method is still not working. There must be something i am not doing right but i havent figured out what exactly in the past 5 hours i have been trying this:

public class Parameter : IEquatable<Parameter>
{
    public string Field { get; set; }
    public string Content { get; set; }

    public bool Equals(Parameter other)
    {
        if (other == null)
        {
            return false;
        }

        return Field.Equals(other.Field) && Content.Equals(other.Content);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 17;
            hash = hash * 23 + Field.GetHashCode();
            hash = hash * 23 + Content.GetHashCode();
            return hash;
        }
    }
}

public class Trigger : IEquatable<Trigger>
{
    public Dictionary<int, Parameter> Parameters { get; private set; }
    private string Event { get; set; }

    public bool Equals(Trigger item)
    {
        if (item == null)
        {
            return false;
        }

        return Event.Equals(item.Event) && Parameters.Equals(item.Parameters);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var hash = 17;
            hash = hash * 23 + Parameters.GetHashCode();
            hash = hash * 23 + Event.GetHashCode();
            return hash;
        }
    }
}

For additional clarity: I have a Dictionary(Trigger, State) that i want to check the keys of so i assumed if i made sure all my sub-classes were equatable i could just use the containskey method, but apparently it does not.

Edit: What i have done now is implement Jon Skeet's Dictionary class and use this to do my checks on:

public override bool Equals(object o)
{
    var item = o as Trigger;
    if (item == null)
    {
        return false;
    }

return Event.Equals(item.Event) && Dictionaries.Equals(Parameters, item.Parameters);
}

public override int GetHashCode()
{
    var hash = 17;
    hash = hash * 23 + Dictionaries.GetHashCode(Parameters);
    hash = hash * 23 + Event.GetHashCode();
    return hash;
}
Was it helpful?

Solution

Dictionary<,> doesn't itself override Equals and GetHashCode - so your Trigger implementations are broken. You would need to work out what equality you wanted and implement it yourself.

I have a sample implementation in protobuf-csharp-port which you might want to look at.

EDIT: Your change still isn't quite right. You should implement equality like this:

return Event.Equals(item.Event) && 
       Dictionaries.Equals(Parameters, item.Parameters);

and implement GetHashCode as:

var hash = 17;
hash = hash * 23 + Dictionaries.GetHashCode(Parameters);
hash = hash * 23 + Event.GetHashCode();
return hash;

OTHER TIPS

You should use the overloaded constructor:

Dictionary<TKey, TValue>(IDictionary<TKey, TValue>, IEqualityComparer<TKey>)

instead of using autoproperty, use a backup field.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top