c#如何正确实现Equals方法以及如何实现GetHashCode方法
本文关键字:方法 实现 何实现 GetHashCode 何正确 Equals | 更新日期: 2023-09-27 17:53:52
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Crystal_Message
{
class Person
{
private string firstName ="";
private string lastName= "";
private string phone="";
public Person(string firstName, string lastName, string phone)
{
this.FirstName = firstName;
this.LastName = lastName;
this.PhoneNumber = phone;
}
public string FirstName
{
get { return firstName; }
private set
{
if (string.IsNullOrWhiteSpace(value)){
throw new ArgumentNullException("Must Include First Name");
}
this.firstName = value;
}
}
public string LastName
{
get { return lastName; }
private set
{
if (string.IsNullOrWhiteSpace(value)){
throw new ArgumentNullException("Must Include Last Name");
}
this.lastName = value;
}
}
public string PhoneNumber
{
get { return phone; }
private set
{
if (string.IsNullOrWhiteSpace(value)){
throw new ArgumentNullException("Must Include Phone Number");
}
this.phone = value;
}
}
public override string ToString()
{
return "First Name: " + this.FirstName + " " + " Last Name: " + this.LastName + " " + " Phone Number: " + this.PhoneNumber;
}
public override bool Equals(object obj)
{
if(obj == null)
{
return false;
}
Person testEquals = obj as Person;
if((System.Object)testEquals == null)
{
return false;
}
return (this.firstName == testEquals.firstName) && (this.lastName == testEquals.lastName) && (this.phone == testEquals.phone);
}
/*
public override int GetHashCode()
{
return
}
*/
}
}
我遵循MSDN的指导方针。两个问题:
- 我是否正确地实现了equals方法?
- 有人能告诉我如何实现GetHashCode正确为我的类?MSDN做x ^ y,但我不能为我的做。
为了避免出现任何问题,GetHashCode
应该使用Equals
使用的所有成员,反之亦然。
所以在你的例子中:
public override int GetHashCode()
{
return firstName.GetHashCode() ^ lastName.GetHashCode() ^ phone.GetHashCode();
}
一种比简单的xor哈希码更常见的方法是使用一个更复杂的公式来组合它们。将各个字段的哈希码乘以不同的数字,例如:
public override int GetHashCode()
{
unchecked
{
return (firstName.GetHashCode() * 33 ^ lastName.GetHashCode()) * 33 ^ phone.GetHashCode();
}
}
(注意unchecked
关键字:整数溢出在这里是预期的,静默环绕正是预期的行为。)
对于你正在处理的具体类型,它可能不会有什么不同,但总的来说,它更好。考虑一个只包含两个整数值的简单类型。还要考虑int
的GetHashCode()
实现只是返回它自己的值。如果你使用一个简单的xor来组合这些值,你将会有很多普通代码的哈希冲突:最简单的例子是,每一对相同的两个值将产生相同的哈希码0。
这里的计算实际上是由Tuple<T1, T2, T3>
完成的计算。我没有按照微软的方式来写,但是实际的计算和数字应该是一样的。
最好记住这两个方法的目的:通过equals,你可以定义在哪种情况下类的两个实例应该被视为相等。如果在你的例子中这是给定的如果姓,名和电话号码相等,那么这是正确的。哈希方法反过来用于对实例进行排序或分布,例如在哈希映射中。它应该足够快,足够好,以避免不必要的集群。因此,在哈希函数中,你经常看到值乘以一个素数。您必须保证相等的对象具有相同的哈希码,而不是相反。所以不同的对象可能有相同的哈希码。