0

I would like override the GetHashCode method on a hashtable in C#.

I use the hashtable as a multidimensional key in a complex object.

How could do that ?

Different order of Keys in hKey must return the same hashCode.

Something like this doesn't work:

Hashtable hkey; 

int i = 0;
foreach (DictionaryEntry de in hkey)
    i ^= de.GetHashCode();

return i;
dymanoid
  • 14,771
  • 4
  • 36
  • 64
Amenis
  • 1
  • 1
  • What have you tried? You could potentially override `GetHashCode` by inheriting the class you want to alter, and then use the new child class instead. – AndreasHassing May 04 '18 at 10:24
  • Why you still use a `HashTable` and not a `Dictionary`? – Tim Schmelter May 04 '18 at 10:27
  • https://codereview.stackexchange.com/questions/32024/calculating-gethashcode-efficiently-with-unordered-list – Tim Schmelter May 04 '18 at 10:28
  • Hmm, the XOR operator does not care about order so the "doesn't work" complaint is not helpful. GetHashCode() becomes useless very quickly when it becomes too slow, iterating an entire collection is not correct. Consider `return hkey.Count;` – Hans Passant May 04 '18 at 13:16
  • See my post below the problem came from the GetHashCode of dictionaryEntry which only take account the Key part. About performance, I keep cache of HashCode ;) – Amenis May 04 '18 at 13:26

2 Answers2

0

You can override GetHashCode() of a Hashtable if you extend it as such:

public class MyHashtable : Hashtable
{
    public override int GetHashCode()
    {
        const int seed = 1009;
        const int factor = 9176;

        var hash = seed;
        foreach (var key in Keys)
        {
            hash = hash * factor + key.GetHashCode();
        }

        return hash;
    }
}

Constants were taken from this answer: https://stackoverflow.com/a/34006336/8006950

More on hashing: http://www.eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx

crazy_p
  • 240
  • 3
  • 6
0

Ok this work fine , thanks to all

    static void Main(string[] args)
    {
        Hashtable h = new Hashtable()
        {
          { "string1", 1 },
          { "string2", 2 }
        };

        int i = GetHashCode(h);

        h = new Hashtable()
        {
          { "string2", 2},
          { "string1", 1 }
        };

        int j = GetHashCode(h);

        Debug.Assert(i == j);

        h = new Hashtable()
        {
          { "string1", 1 },
          { "string2", 2 }
        };

        i = GetHashCode(h);

        h = new Hashtable()
        {
          { "string2", 3},
          { "string1", 1 }
        };

        j = GetHashCode(h);

        Debug.Assert(i != j);
    }

    static int GetHashCode(Hashtable ht)
    {
        if (ht.Count == 0) return ht.GetHashCode();

        int h = 0;
        foreach(DictionaryEntry de in ht)
        {
            h ^= new { de.Key, de.Value }.GetHashCode();
        }
        return h;
    }
Amenis
  • 1
  • 1