如果我有引用类型对象,我创建了两个具有相同属性的对象 他们会有相同的哈希码吗?
样本类:
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()??
编辑:我尝试了这段代码并获得了不同的结果,但测试字符串上的东西给了我相同的结果
那我为什么要问
答案 0 :(得分:1)
如果Person是结构,那么将从成员值生成哈希码,您将获得相同的结果。但是,对于类,默认的哈希码实现将根据内存引用为每个对象提供唯一的哈希码。
所以在这种情况下,如果你想要p1和p2的相同哈希码,你必须提供自己的实现。
答案 1 :(得分:1)
您有责任自己实施GetHashCode
。如果你不这样做,他们就不会有相同的哈希码。
答案 2 :(得分: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中实现的equals。 (隐式地在C#中扩展Object的所有类) 像这样:
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"
的人员。你怎么会找到这个人的?你会逐个遍历所有的名字,并检查那个人是否等于amy?但那将是非常缓慢的,如果amy是这个名单中的第一百万人呢?我们如何提高绩效?
输入Hashcodes。
假设您编写了一个简单的哈希码算法: 哈希码是人名中每个字母的每个数字的总和。
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
。
现在,您将拥有一个名为“buckets”的列表,而不是普通列表。您的哈希码决定您去哪个桶。 amy
38
如果38
进入货架may
,则会有一个密码。
现在假设我们有另一个人,姓名38
,她的名字中有相同的字母,所以她的哈希码也是38
,她也进入了38
现在,每当你想检查这个列表中是否存在amy时。我们首先检查她的哈希码,38
,现在我们去看看桶38,然后遍历桶38
中的所有对象,我们检查桶amy
中的任何对象是否与amy匹配如果为true,则返回true,如果为false,则返回false。因此,如果您有一百万人,那么您必须要知道的列表是否存在此列表中{{1}}是否会大幅减少。
所以基本上如果你要使用哈希码,你将不得不遵守以下规则:
这基本上就是它的主旨。
答案 3 :(得分:0)
默认情况下,他们不会(对于参考类型)。你可以尝试一下,看看。
如果您希望它们具有相同的哈希码,则必须相应地编写自己的GetHashCode()。