"gethashcode override of object containing generic array" Code Answer

5

because of the problems raised in this thread, i'm posting another reply showing what happens if you get it wrong... mainly, that you can't use the array's gethashcode(); the correct behaviour is that no warnings are printed when you run it... switch the comments to fix it:

using system;
using system.collections.generic;
using system.linq;
static class program
{
    static void main()
    {
        // first and second are logically equivalent
        simpletablerow<int> first = new simpletablerow<int>(1, 2, 3, 4, 5, 6),
            second = new simpletablerow<int>(1, 2, 3, 4, 5, 6);

        if (first.equals(second) && first.gethashcode() != second.gethashcode())
        { // proven equals, but gethashcode() disagrees
            console.writeline("we have a problem");
        }
        hashset<simpletablerow<int>> set = new hashset<simpletablerow<int>>();
        set.add(first);
        set.add(second);
        // which confuses anything that uses hash algorithms
        if (set.count != 1) console.writeline("yup, very bad indeed");
    }
}
class simpletablerow<t> : iequatable<simpletablerow<t>>
{

    public simpletablerow(int id, params t[] values) {
        this.id = id;
        this.values = values;
    }
    public int id { get; private set; }
    public t[] values { get; private set; }

    public override int gethashcode() // wrong
    {
        return id.gethashcode() ^ values.gethashcode();
    }
    /*
    public override int gethashcode() // right
    {
        int hash = id;
        if (values != null)
        {
            hash = (hash * 17) + values.length;
            foreach (t t in values)
            {
                hash *= 17;
                if (t != null) hash = hash + t.gethashcode();
            }
        }
        return hash;
    }
    */
    public override bool equals(object obj)
    {
        return equals(obj as simpletablerow<t>);
    }
    public bool equals(simpletablerow<t> other)
    {
        // check for null
        if (referenceequals(other, null))
            return false;

        // check for same reference
        if (referenceequals(this, other))
            return true;

        // check for same id and same values
        return id == other.id && values.sequenceequal(other.values);
    }
}
By Potsky on February 26 2022
Only authorized users can answer the Search term. Please sign in first, or register a free account.