2012-08-30 40 views
-4
对象

如果我有引用类型的对象,我创建了两个对象具有相同属性 将它们有相同的哈希码?将哈希码给我相同的结果为具有相同属性

示例类:

class Person 
{ 
    int id; 
    string name; 

    public Person(int pid, string pname) 
    { 
     this.id = pid; 
     this.name = pname; 
    } 
} 

然后定义两个对象:

Person p1 = new Person(1,"xxx"); 
Perdon p2 = new Person(1,"xxx"); 

//p1.GetHashCode()= p2.GetHashCode()?

编辑:我想这个代码,并得到了不同的充的结果,但对字符串测试的东西给了我同样的结果
我为什么要问

+6

你运行过吗?结果是什么?测试你自己的时间比在这里问的要少得多。 – Oded

+0

您不希望它们具有相同的哈希码。 –

+0

@已付给你的权利,但我试图在sa字符串上,我得到了相同的结果,然后在这个类上尝试它,并得到了相同的rsult,令人困惑 – Star

回答

1

你是对自己负责执行GetHashCode。如果你不这样做,他们将不会有相同的散列码,尽管他们应该。

+1

“虽然他们应该” - 我认为他们不应该。 Person是一个可变参考类型。 –

+0

@HenkHolterman:我在这里看不到任何可变性。 –

+0

@亨克是对的 - 这些字段没有被声明为'readonly',所以可以被突变。 – Oded

1

如果人是一个结构,则哈希码将被从成员值中生成,你会得到相同的结果。但是,对于类,默认的哈希码实现将根据其内存引用为每个对象提供唯一的哈希码。

因此,在这种情况下,如果你想为P1和P2相同的哈希码,你必须提供自己的实现。

+2

也许应该补充一点,他们*应该*确实不会得到相同的哈希代码,因为如果哈希代码不相同(为了使哈希符合它们的目的)提供相等的良好指示),并且如果p1和p2是类类型,则p1.Equals(p2)== false,因为类类型的相等的默认概念是对象标识。 – JohnB

+1

如果它是一个结构体,我建议给它添加一个'GetHashCode()'。为结构生成合理的默认哈希码的代码非常聪明,但令人遗憾的是,巧妙有点沉重。 –

0

默认情况下,他们不会(为引用类型)。你可以试试看看。

如果你希望他们有相同的哈希码,你必须()相应编写自己的GetHashCode。

1

在这里看到的默认实现: http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx

GetHashCode方法的默认实现不保证唯一的返回值不同的对象。此外,.NET Framework不保证GetHashCode方法的默认实现,并且它返回的值在不同版本的.NET Framework之间将保持不变。因此,此方法的默认实现不能用作用于散列目的的唯一对象标识符。

但我觉得你真的想知道的是哈希码是如何工作的。

比方说,你有下面的类:

public Person 
{ 
    private string name; 
    public Person(Name name) 
    { 
     this.name = name; 
    } 
} 

现在,让我们说你要比较两个人,检查他们是否有相同的名字,你是怎么做到这一点?您重写在Object中实现的等于。 (在C#中的所有类继承对象隐含的) 像这样:

public Person 
{ 
    private string name; 
    public Person(Name name) 
    { 
     this.name = name; 
    } 

    public override bool Equals(Object obj) 
    { 
     if(obj == null) 
      return false // not equal if obj is null 

     Equals temp = obj as Equals; // temp set to null if obj can not be cast to equals 
     if(p == null) 
      return false 

     // if code gets here, the code object passed is an instance of Equals. 
     // Now we have to check if the strings match. 
     bool isEqual = p.name == this.name; // set if the two names match 
     return isEqual; // return if these two match 
    } 
} 

所以,现在,你可以检查,如果两个人都是平等的。 例子:

Person p1 = new Person("Jack"); 
Person p2 = new Person("Jack"); 
Person p3 = new Person("Jill"); 
Object p4 = new Person("Jill"); 

p1.Equals(p2) // returns true 
p1.Equals(p3) // returns false 
p4.Equals(p1) // returns false 
p4.Equals(p3) // returns true 

现在,让我们说你有一个巨大的人一样,一百万的列表,你想知道,如果命名"amy"的人在这个列表中存在。你如何找到这个人?你会一个一个地循环所有的名字,并检查这个人是否等于艾米?但是这样会很慢,如果艾米是这个名单中的第100万人呢?我们如何提高性能?

输入哈希码。

让我们假设你写一个简单的哈希码算法: 哈希码是人名中每个字母的每个数字的总和。

public Person 
{ 
    private string name; 
    public Person(Name name) 
    { 
     this.name = name; 
    } 

    public override bool Equals(Object obj) 
    { 
     if(obj == null) 
      return false // not equal if obj is null 

     Equals temp = obj as Equals; // temp set to null if obj can not be cast to equals 
     if(p == null) 
      return false 

     // if code gets here, the code object passed is an instance of Equals. 
     // Now we have to check if the strings match. 
     bool isEqual = p.name == this.name; // set if the two names match 
     return isEqual; // return if these two match 
    } 

    public override int GetHashCode() 
    { 
     int sum = 0; 
     foreach(char c in this.name) 
     { 
      sum += c; 
     } 
     return sum; 
    } 
} 

因此,如果我们有amy她的哈希码会1 + 13 + 25,所以38

现在不是一个普通的列表,而是有一个名为“桶”的列表。你的散列码决定你去哪个桶。 amy has hascode如果38她去桶38

现在让我们说我们有另外一个人,名字may,她有她的名字相同的字母,所以她的哈希码也38,她也进入水桶现在38

,只要你想,以检查是否艾米存在在这个列表中。我们首先检查她的哈希码,其中38,现在我们去查看桶38,并且循环遍历桶38中的所有对象,我们检查桶38中的任何对象是否匹配amy,如果为true,则返回true,如果为false,则返回false 。所以如果你有一百万人,那么你必须做的检查清单才能知道amy是否存在于这个清单中,这个清单会大大减少。

所以基本上,如果你要使用的哈希码你得遵守以下规则:

  • 您必须覆盖&实现equals如果你要使用的哈希码。
  • 的两个对象,其中的Equals返回true,就必须有相同的hashCode
  • 两个对象是不同的可能具有相同的哈希码,但不一定必须是相同的。

这基本上就是它的要义。

+0

很长的答案,但它并没有真正关注核心问题:什么是默认行为。 –

+0

@HenkHolterman我想你是对的,但我尝试t_t。 *编辑答案*。但我想我回答了他想问的问题,因为他的问题看起来好像他不知道什么是哈希码。 – ProgrammerAtWork

相关问题