如果 2 个数组对象包含相同的值,则生成相同的哈希码

Producing the same hashcode if 2 array objects contain the same values

我正在尝试为我的一个 classes 计算散列码,问题是:这个 class 有一个 byte[],其中 returns 每个不同的散列目的。我已经制作了 class 的 2 个对象,并且都用一个新的 byte[0].

实例化了

在覆盖 Equals 运算符时,我使用了 Enumberable.SquenceEqual() 来确保两个数组的内容相同。但是,如果数组 return 的内容相同,我如何确保它们具有相同的哈希码?

我的代码:

    public override bool Equals(object obj)
    {
        return Equals(obj as MessageType);
    }

    {
        if (messageType != null)
        {
            return (this.Identification == messageType.Identification) &&
                (this.ActivateWindow == messageType.ActivateWindow) &&
                (this.Logging == messageType.Logging) &&
                (Enumerable.SequenceEqual(this.Pictogram, messageType.Pictogram) == true) &&
                (this.Priority == messageType.Priority) &&
                (this.Procedure == messageType.Procedure);
        }

        return false;
    }

    public override int GetHashCode()
    {
        var result = this.Identification != null ? this.Identification.GetHashCode() : 0;
        result = (result * 397) ^ this.ActivateWindow.GetHashCode();
        result = (result * 397) ^ this.Logging.GetHashCode();
        result = (result * 397) ^ ((this.Pictogram != null) ? this.Pictogram.GetHashCode() : 0);
        result = (result * 397) ^ this.Priority.GetHashCode();
        result = (result * 397) ^ ((this.Procedure != null) ? this.Procedure.GetHashCode() : 0);
        return result;
    }

据我了解,您应该在 Equals 中使用 Enumerable.SequenceEqual 并在 GetHashCode() 中使用某种聚合:

   byte[] extraData = ...

   ...

   public bool Equals(MessageType other) {
     ...

     if (!Enumerable.SequenceEqual(extraData, other.extraData))
       return false;

     ...  
   } 

   public override int GetHashCode() {
     unchecked { // we don't want IntegerOverflow exceptions to be thrown
       int result = ...

       ...  
       // let's combine hashes with xor
       result ^= extraData == null 
        ? 0
        : extraData.Aggerate(0, (s, a) => s ^ a); // ...and aggerate with xor as well

       ...

       return result;
     }
   }

万一 extraData 可能 相当长 (例如令人震惊的 1 GB),您可能需要限制计算到 10 第一项:

   result ^= extraData == null 
     ? 0
     : extraData.Take(10).Aggerate(0, (s, a) => s ^ a);