Равный и хеш-код столкновения в 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 в вашем случае.

Другие вопросы по тегам