簡體   English   中英

為ValueObject實現GetHashCode和Equals方法的實現

[英]Implemeting GetHashCode and Equals methods for ValueObjects

NHibernate文檔中有一段內容:

注意:如果定義復合元素的ISet ,正確實現Equals()GetHashCode()非常重要。

那里的correctly含義是什么? 是否需要為域中的所有值對象實現這些方法?

擴展我的問題

在文章馬克連接用戶白漿指出:

正確實現GetHashCode()實際上非常困難,因為除了已經提到的Marc規則外,哈希碼在對象的生存期內不應更改。 因此,用於計算哈希碼的字段必須是不可變的。

當我與NHibernate合作時,我終於找到了解決該問題的方法。 我的方法是根據對象的ID計算哈希碼。 只能通過構造函數來設置ID,因此,如果您想更改ID(這是不太可能的),則必須創建一個具有新ID和新哈希碼的新對象。 這種方法最適合GUID,因為您可以提供一個無參數的構造函數,該構造函數會隨機生成一個ID。

我突然意識到我在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()嗎?

正確地意味着, GetHashCode預期相等的實體返回相同的哈希碼。 因為2個實體的相等性是通過比較該代碼來實現的。

另一方面,這意味着對於不相等的實體,必須盡可能保證哈希碼的唯一性。

EqualsGetHashCode的文檔對此進行了很好的解釋,並包括有關實現值對象的特定指南。 對於值對象,如果對象是相同類型並且公共字段和私有字段相等,則Equals為true。 但是,此說明適用於框架值類型,您可以通過覆蓋它來自由創建自己的Equals。

GetHashCode有兩個必須遵循的規則:

  • 如果兩個對象比較相等,則每個對象的GetHashCode方法必須返回相同的值。 但是,如果兩個對象的比較不相等,則兩個對象的GetHashCode方法不必返回不同的值。

  • 只要沒有修改確定對象的Equals方法返回值的對象狀態,對象的GetHashCode方法就必須始終返回相同的哈希碼。 請注意,這僅適用於當前執行的應用程序,並且如果再次運行該應用程序,則可以返回不同的哈希碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM