Существует отрывок из NHibernate
документации:Implemeting GetHashCode и Equals методы ValueObjects
Примечание: если вы определяете
ISet
составных элементов, очень важно для реализацииEquals()
иGetHashCode()
правильно.
Что такое correctly
означает, что там? Нужно ли реализовать эти методы для всех объектов значений в домене?
РАСШИРЕНИЕ МОЙ ВОПРОС
В статье Марк прилагается пользователь Albic состояния:
Это на самом деле очень трудно правильно реализовать
GetHashCode()
, потому что, в дополнение к правилам Марк уже упоминалось , хэш-код не должен меняться в течение всего жизненного цикла объекта. Поэтому поля, которые используются для вычисления хэш-кода, должны быть неизменными.Я, наконец, нашел решение этой проблемы, когда я работал с
NHibernate
. Мой подход заключается в вычислении хеш-кода из идентификатора объекта. Идентификатор может быть установлен только с помощью конструктора, поэтому, если вы хотите изменить ID, что очень маловероятно, вам нужно создать новый объект с новым идентификатором и, следовательно, новый хэш-код. Этот подход лучше всего работает с GUID, потому что вы можете предоставить конструктор без параметров, который случайным образом генерирует идентификатор.
я вдруг понял, что у меня есть в моем AbstractEntity
классе:
public abstract class AbstractEntity<T> where T : AbstractEntity<T> {
private Nullable<Int32> hashCode;
public virtual Guid Id { get; protected set; }
public virtual Byte[] Version { get; set; }
public override Boolean Equals(Object obj) {
var other = obj as T;
if(other == null) {
return false;
}
var thisIsNew = Equals(this.Id, Guid.Empty);
var otherIsNew = Equals(other.Id, Guid.Empty);
if(thisIsNew && otherIsNew) {
return ReferenceEquals(this, other);
}
return this.Id.Equals(other.Id);
} // public override Boolean Equals(Object obj) {
public override Int32 GetHashCode() {
if(this.hashCode.HasValue) {
return this.hashCode.Value;
}
var thisIsNew = Equals(this.Id, Guid.Empty);
if(thisIsNew) {
this.hashCode = base.GetHashCode();
return this.hashCode.Value;
}
return this.Id.GetHashCode();
} // public override Int32 GetHashCode() {
public static Boolean operator ==(AbstractEntity<T> l, AbstractEntity<T> r) {
return Equals(l, r);
}
public static Boolean operator !=(AbstractEntity<T> l, AbstractEntity<T> r) {
return !Equals(l, r);
}
} // public abstract class AbstractEntity<T>...
Поскольку все components
вложены в entities
я должен затем реализовать Equals()
и GetHashCode()
для них?
Связанный: http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overridden?rq=1 –