1

i have a Dictionary of types (Dictionary) with a custom comparer, because we want to store relationships between 2 given types (for a MVVM pattern), and i need help comming up with a way to get custom EqualityComparer to work.

Doing some research i found that the GetHashCode method gets called before the Equals method, how can i get the hashcodes right?, the expected behavior it's that if i try to get a "Square" from my dictionary, and it has a "GeometricShape" already in it, it returns the value of the "GeometricShape", i can't find a way to hash it in a way that i gives the expected result

public class DictionaryComparer : EqualityComparer<Type>
{
    public override bool Equals(Type x, Type y)
    {            
        return x.IsAssignableFromType(y);
    }

    public override int GetHashCode(Type obj)
    {
        return obj.GetHashCode();
    }
}
Loucry
  • 23
  • 4
  • This question needs some clarification. Are you trying to tell the Dictionary that, if you access the key X (that is not on the Dictionary) and it has the key X', it should return the value for the later? If so, are you aware that you will not be able to add Keys that are assignable to another key already on the Dictionary? – Gabriel Rainha Nov 21 '16 at 23:36
  • I have a feeling (though I might be wrong) that you are trying to use the wrong tool for the job. Can you explain what you are trying to achieve with this? – Botond Balázs Nov 21 '16 at 23:44
  • MVVM and Dictionaries. That's a code smell. I'd first suggest you switch to KeyedCollections instead, or remove the need for a keyed collection completely. As for what you're trying to equate... not sure at all. –  Nov 22 '16 at 14:26

1 Answers1

2

You can't have comparer that uses "assignable from" as equivalency operation.

Equals has particular rules assumed by classes that rely on it. If you break the rules results of using such comparer would be essentially random shuffle.

See Guidelines for Overloading Equals()

x.Equals(x) returns true.
x.Equals(y) returns the same value as y.Equals(x)
if (x.Equals(y) && y.Equals(z)) returns true, then x.Equals(z) returns true.

I'm not really sure how to solve your particular case, possibly if you just need to map one type to another you just have Dictionary<Type,Type> and put types directly to it.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179