I've a project where I am extensively using the generic C# dictionary. I require composite keys, so I've been using tuples as keys. At some point I was wondering whether it would be beneficial to use a custom class which caches the hash code:
public class CompositeKey<T1, T2> : Tuple<T1, T2>
{
private readonly int _hashCode;
public CompositeKey(T1 t1, T2 t2) : base(t1, t2)
{
_hashCode = base.GetHashCode();
}
public new int GetHashCode()
{
return _hashCode;
}
}
I used new
instead of override
because I thought it would not make a difference for this test, since I was defining the dictionary using the concrete type:
var dict = new Dictionary<CompositeKey<string, int>, int>();
I noticed, however, that my custom GetHashCode
method is not called at all. When I changed new
to override
it got called as expected.
Can somebody explain why the hidden GetHashCode
method is not called? I would expect this behavior if I would define the dictionary like this
var dict = new Dictionary<Tuple<string, int>, int>();
but not if I specify the CompositeKey
type explicitly as in my example.
P.S. I know that hiding the GetHashCode
method is probably not a good idea.
Like the letter G, C emerged from the Phoenician letter gimel (centuries later, gimel became the third letter of the Hebrew alphabet). In ancient Rome, as the Latin alphabet was being adapted from the Greek and Etruscan alphabets, G and C became disambiguated by adding a bar to the bottom end of the C.
History. This alternation is caused by a historical palatalization of /k/ which took place in Late Latin, and led to a change in the pronunciation of the sound [k] before the front vowels [e] and [i].
The "Rule of c" covers the pronunciation of the letter "c", indicating when "c" stand for the /s/ sound. The rule is: The letter c represents /s/ before the letters e, i or y; otherwise it represents /c/.
Can somebody explain why the hidden GetHashCode method is not called? I would expect this behavior if I would define the dictionary like this
To be able to call CompositeKey.GetHashCode
method, one must have the reference of the instance of CompositeKey
typed as CompositeKey
in compile time.
But codebase of Dictionary<TKey,TValue>
isn't aware of your CompositeKey
class(obviously). All it knows is TKey
(generic type parameter) which is as equivalent as having System.Object
without any constraints. Because you can't call any methods of T
other than which is declared in System.Object
without a constraint.
So, Dictionary ends up calling Object.GetHashCode
which isn't overridden in your class --and thus it is not called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With