Единственный способ, которым вы действительно можете это сделать, - переопределить bool Object.Equals(object other)
, чтобы вернуть true, когда выполняются условия для равенства, и в противном случае вернуть false. Вы также должны переопределить int Object.GetHashCode()
, чтобы вернуть int из всех данных, которые вы рассматриваете при переопределении Equals()
.
Отметим, что в контракте для GetHashCode()
указано, что возвращаемое значение должно быть равным для двух объектов, когда Equals()
вернет true при их сравнении. Это означает, что return 0;
является допустимой реализацией GetHashCode()
, но это приведет к неэффективности, когда объекты вашего класса используются в качестве ключей словаря или хранятся в HashSet<T>
.
Путь я реализую равенства, как это:
public class Foo : IEquatable<Foo>
{
public bool Equals(Foo other)
{
if (other == null)
return false;
if (other == this)
return true; // Same object reference.
// Compare this to other and return true/false as appropriate.
}
public override bool Equals(Object other)
{
return Equals(other as Foo);
}
public override int GetHashCode()
{
// Compute and return hash code.
}
}
Простой способ реализации GetHashCode()
является XOR вместе хэш-коды всех данных вы считаете равенства в Equals()
. Так что если, например, свойства вы сравниваете равенства являются string FirstName; string LastName; int Id;
, ваша реализация может выглядеть следующим образом:
public override int GetHashCode()
{
return (FirstName != null ? FirstName.GetHashCode() : 0)^
(LastName != null ? LastName.GetHashCode() : 0)^
Id; // Primitives of <= 4 bytes are their own hash codes
}
Я обычно делать не переопределение операторов равенства, поскольку большую часть времени я обеспокоенный с равенством только для целей словарных ключей или коллекций. Я бы рассмотрел только переопределение операторов равенства, если вы скорее всего сделаете больше сравнений по значению, чем по ссылке, поскольку оно синтаксически менее подробное. Однако вы должны помнить об изменении всех мест, где вы используете ==
или !=
на вашем объекте (в том числе при реализации Equals()
!) Использовать Object.ReferenceEquals()
или лить оба операнда в object
. Эта неприятная gotcha (которая может вызвать бесконечную рекурсию в вашем тесте равенства, если вы не внимательны) является одной из основных причин, по которым я редко переопределяю этих операторов.
Каковы ваши условия при равных условиях? – BoltClock
В принципе, все значения в этих членах строки, двойных членах и массиве должны быть одинаковыми! – siva
Возможный дубликат http://stackoverflow.com/questions/506096/comparing-object-properties-in-c – RameshVel