В чем разница между obj1.Equals(obj2) и статическим Object.Equals(obj1, obj2) в C#?

Судя по документации Microsoft, оба Equals-метода практически одинаковы. Но я наткнулся на что-то очень странное. в моем проекте Silverlight у меня есть два экземпляра одного класса, которые переопределяют Equals. Если я запрашиваю inst1.Equals(inst2) или inst2.Equals(inst1), я всегда получаю истину как результат. Но Object.Equals(inst1, inst2) возвращает false. Как это возможно?

Есть идеи?

Спасибо, роко

4 ответа

obj1.Equals предполагает, что obj1 не null, object.Equals работает даже на null ценности. Это не объясняет поведение, которое вы видите, хотя; Я думаю, что вы должны предоставить код, чтобы воспроизвести его для лучшего ответа.

obj1.Equals может быть переопределено, Object.Equals не может. Другими словами, Object.Equals является базовой реализацией метода Equals, который вы получаете бесплатно, если не переопределите его. Так как вы переопределили это, две реализации отличаются и могут давать разные результаты.

Я думаю, что Object.Equals проверит, являются ли 2 аргумента одной и той же ссылкой, то есть они указывают на одно и то же пространство памяти.

MyClass.Equals может иметь различную реализацию, так что 2 класса, которые не являются одинаковыми ссылками, могут фактически быть равными (в зависимости от их полей и свойств).

Будьте осторожны, чтобы правильно реализовать IEquatable<T>, Я сделал следующую ошибку:

public class SubjectDTO: IEquatable<SubjectDTO>
{
    public string Id;

    public bool Equals(SubjectDTO other)
    {
        return Object.Equals(Id, other.Id);
    }

    public override int GetHashCode()
    {
        return Id == null ? 1 : Id.GetHashCode();
    }
}

Выглядит хорошо, верно? Но когда вы попробуете это, вы обнаружите удивительный результат:

var a = new SubjectDTO() { Id = "1"};
var b = new SubjectDTO() { Id = "1"};
Console.WriteLine(Object.Equals(a, b));
Console.WriteLine(a.Equals(b));

False
True

А? Ну, это важно, чтобы overideEquals(object other):

public override bool Equals(object other)
{
    return other == null ? false : Equals(other as SubjectDTO);
}

Когда вы добавляете его в SubjectDTO класс, он будет работать как положено.

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