GetHashCode override of object containing generic array

前端 未结 9 1702
情歌与酒
情歌与酒 2020-12-04 05:35

I have a class that contains the following two properties:

public int Id      { get; private set; }
public T[] Values  { get; private set; }
<
9条回答
  •  情书的邮戳
    2020-12-04 05:51

    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 first = new SimpleTableRow(1, 2, 3, 4, 5, 6),
                second = new SimpleTableRow(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> set = new HashSet>();
            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 : IEquatable>
    {
    
        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);
        }
        public bool Equals(SimpleTableRow 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);
        }
    }
    

提交回复
热议问题