Равный и хеш-код столкновения в C#
Я написал следующий код в C#:
public class Person
{
private string idNumber;
private string personName;
public Person(string name, string id)
{
this.personName= name;
this.idNumber= id;
}
public override bool Equals(Objectobj)
{
Person personObj= obj as Person;
if(personObj== null)
return false;
else
return idNumber.Equals(personObj.idNumber);
}
public override int GetHashCode()
{
return this.idNumber.GetHashCode();
}
}
public static void Main()
{
Person p1 = new Person("John", "63412895");
Person p2 = new Person("Jack", "63412895");
Console.WriteLine(p1.Equals(p2));
Console.WriteLine(Object.Equals(p1, p2));
}
я не понимаю, почему второй Console.WriteLine()
возвращает истину??? первый возвращает истину, так как я переопределяю равный метод. но второй относится к равным в классе объектов. пожалуйста, объясни.
5 ответов
Статический object.Equals
метод определяется как
public static bool Equals(Object objA, Object objB)
{
if (objA==objB) {
return true;
}
if (objA==null || objB==null) {
return false;
}
return objA.Equals(objB);
}
Так что внутренне он использует переопределенный Equals
после null
чеки.
Чтобы сравнить ссылки, используйте object.ReferenceEquals
или приведение к object
и использовать ==
оператор.
object.ReferenceEquals(p1, p2)
(object)p1 == (object)p2
Цитата из документации MSDN по Object.Equals(Object, Object)
Если два объекта не представляют одну и ту же ссылку на объект и ни один не является нулевым, он вызывает objA.Equals(objB) и возвращает результат. Это означает, что если objA переопределяет метод Object.Equals(Object), вызывается это переопределение.
Я верю, что именно так и происходит в вашем сценарии. Поскольку вы переопределили Equals
метод, он вызывается внутри Object
статический метод.
Вторая строка кода внутренне проверяет, является ли p1 нулевым, и вызывает первую строку.
Таким образом, вы не можете ожидать разных результатов при вызове почти одного и того же метода.
p1.Equals(p2);
Object.Equals(p1, p2);
Я думаю, что это связано с тем, что вы также переопределяете GetHashcode, который используется Object.Equals. Это мое предположение.
Вы отвергли GetHashCode. Вот что использует объектное равенство. Классическим примером в.Net являются два объекта objStringA ="MyVal" и ObjStringB = 'MyVal", которые будут возвращаться равными, потому что строка переопределяет хеш-код get.
Как будто ты дважды это преодолел. Я не уверен, что вам нужно было переопределить оператор Equals в вашем случае.