【问题标题】:List of objects equality using .GetHashCode()使用 .GetHashCode() 的对象相等列表
【发布时间】:2019-11-03 02:36:40
【问题描述】:

我想了解GetHashCode 方法如何处理对象列表以实现相等性。给定这个例子:

var user1 = new User { Id = Guid.NewGuid().ToString(), Name = "Chris" };
var user2 = new User { Id = Guid.NewGuid().ToString(), Name = "Jeff" };

var userList1 = new List<User> { user1, user2 }.OrderBy(o => o.Id);
var userList2 = new List<User> { user1, user2 }.OrderBy(o => o.Id);

var usersList1Hash = userList1.GetHashCode();
var usersList2Hash = userList2.GetHashCode();

var userListsEqual = usersList1Hash == usersList2Hash; // false

var userList1Json = JsonConvert.SerializeObject(userList1);
var userList2Json = JsonConvert.SerializeObject(userList2);

var usersList1JsonHash = userList1Json.GetHashCode();
var usersList2JsonHash = userList2Json.GetHashCode();

var userListsJsonEqual = usersList1JsonHash == usersList2JsonHash; // true
  1. 为什么在比较哈希码时对象列表不相等

  2. 为什么在序列化为 JSON 字符串并比较哈希码时,对象列表相等

【问题讨论】:

  • 您看到的是Object.GetHashCode()String.GetHashCode() 之间的差异。
  • 虽然列表是相同类型并且包含相同顺序的相同对象,但根据它们的哈希码,它们不被认为是相等的。另请参阅ideone.com/kE2gSj
  • @JeroenMostert 啊,好吧!但是是什么让 object 散列不同?
  • object.GetHashCode() 生成对象引用的哈希。 2 个实例 = 2 个不同的引用。
  • 太好了。谢谢@Oliver

标签: c# object json.net hashcode


【解决方案1】:

GetHashCode 函数给出一个对象的有符号 int32 散列。

来自 MSDN。

两个相等的对象返回相等的哈希码。然而, 反过来是不正确的:相等的哈希码并不意味着对象 相等,因为不同的(不相等的)对象可以有相同的哈希 代码。

GetHashCode 是一个虚函数,可以被覆盖。调用JsonConvert.SerializeObject 函数后得到的字符串。 string 类有自己的 GetHashCode 实现,它基于字符串的内容。像下面的东西。这就是它匹配的原因。

public class string {  
  char[] str = null;
  ...
  public string(char[] input) {
    this.str = input;
  }

  public override GetHashCode() {
    //Logic to convert str to int 32 based on string contents;

    return Convert.ToInt32(str);
  }
}

【讨论】:

  • “如果两个对象的哈希值相等,则对象相等。” 这是错误的。如果两个对象的散列相等,则(使用分布良好的散列函数)对象是可能的,但不能保证相等。这是一个非常重要的区别。
  • @spender 对。这就是我想写的。我更新了答案。
猜你喜欢
  • 2019-06-12
  • 2014-12-24
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 2016-09-23
  • 2012-10-23
  • 2021-02-22
相关资源
最近更新 更多