.net-4.0 - 为什么这些哈希码相等?

标签 .net-4.0 gethashcode

这个测试失败了:

var hashCode = new 
{
    CustomerId = 3354,
    ServiceId = 3,
    CmsThematicId = (int?)605,
    StartDate = (DateTime?)new DateTime(2013, 1, 5),
    EndDate = (DateTime?)new DateTime(2013, 1, 6)
}.GetHashCode();
var hashCode2 = new
{
    CustomerId = 1210,
    ServiceId = 3,
    CmsThematicId = (int?)591,
    StartDate = (DateTime?)new DateTime(2013, 3, 31),
    EndDate = (DateTime?)new DateTime(2013, 4, 1)
}.GetHashCode();
Assert.AreNotEqual(hashCode, hashCode2);

你能告诉我为什么吗?

最佳答案

你发现这个巧合真是太神奇了。

匿名类有一个生成的GetHashCode()方法,它通过组合所有属性的散列码来生成散列码。

计算基本上是这样的:

  public override int GetHashCode()
  {
    return        -1521134295 * 
                ( -1521134295 * 
                ( -1521134295 * 
                ( -1521134295 * 
                ( -1521134295 * 
                   1170354300 + 
                  CustomerId.GetHashCode()) +
                  ServiceId.GetHashCode()) + 
                  CmsThematicId.GetHashCode()) + 
                  StartDate.GetHashCode()) + 
                  EndDate.GetHashCode();
  }

如果您更改任何字段的任何值,则哈希码会发生变化。您发现两组不同的值恰好获得相同的哈希码这一事实纯属巧合。

请注意,哈希码不一定是唯一的。不可能说哈希码总是唯一的,因为对象的数量可能比哈希码多(尽管对象很多)。好的散列码提供随机分布的值。

注意:以上来自.NET 4。不同版本的.NET可能不同,Mono也不同。

如果您想实际比较两个对象是否相等,请使用 .Equals()。对于匿名对象,它比较每个字段。一个更好的选择是使用 NUnit 约束来比较每个字段并报告哪个字段不同。我在这里发布了一个约束:

https://stackoverflow.com/a/2046566/118703

关于.net-4.0 - 为什么这些哈希码相等?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14585041/

相关文章:

wpf - 无法使用新的 2009 XAML 原语,为什么?

c# - 如何将数组拆分为一组 n 个元素?

c# - Contains 如何返回 false 但 GetHashCode() 返回相同的数字,而 Equals 返回 true?

.NET 4.0 有一个新的 GAC,为什么?

.net-4.0 - EventSource .net 4.0 生成 list

c# - OpenID,如何开发提供者

c# - GetHashCode() 返回值应该基于原始对象的状态还是修改后的对象的状态?

nhibernate - 这是否解决了 Nhibernate 身份问题和 GetHashCode 问题?

c# - GetType().GetHashCode() 是否保证唯一性?