1

ドキュメントからの一節がありNHibernateます:

注: 複合要素の を定義する場合は、正しくISet実装することが非常に重要です。Equals()GetHashCode()

とはcorrectlyどういう意味ですか? ドメイン内のすべての値オブジェクトに対してこれらのメソッドを実装する必要がありますか?

私の質問を拡張する

記事の中で、Marcが添付したユーザーAlbicは次のように述べています。

GetHashCode()Marc が既に述べた規則に加えて、ハッシュ コードはオブジェクトの存続期間中に変更されるべきではないため、正しく実装するのは実際には非常に困難です。したがって、ハッシュ コードの計算に使用されるフィールドは不変でなければなりません。

で作業していたときに、ようやくこの問題の解決策を見つけましたNHibernate。私のアプローチは、オブジェクトの ID からハッシュ コードを計算することです。ID はコンストラクターを介してのみ設定できるため、ID を変更したい場合 (これはほとんどありません)、新しい ID と新しいハッシュ コードを持つ新しいオブジェクトを作成する必要があります。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()ますか?

4

2 に答える 2

1

正しくは、等しいと予想さGetHashCodeれるエンティティに対して同じハッシュ コードを返すことを意味します。2 つのエンティティの等価性は、そのコードの比較によって作られるためです。

反対に、等しくないエンティティについては、ハッシュ コードの一意性を可能な限り保証する必要があることを意味します。

于 2013-04-11T11:03:21.900 に答える
1

EqualsGetHashCodeのドキュメントでは、これについて詳しく説明されており、値オブジェクトの実装に関する具体的なガイダンスが含まれています。値オブジェクトの場合、オブジェクトが同じ型で、パブリック フィールドとプライベート フィールドが等しい場合、Equals は true です。ただし、この説明はフレームワークの値の型に適用され、オーバーライドして独自の Equals を自由に作成できます。

GetHashCode には、従わなければならない 2 つの規則があります。

  • 2 つのオブジェクトを比較して等しい場合、各オブジェクトの GetHashCode メソッドは同じ値を返す必要があります。ただし、2 つのオブジェクトが等しくない場合、2 つのオブジェクトの GetHashCode メソッドは異なる値を返す必要はありません。

  • オブジェクトの GetHashCode メソッドは、オブジェクトの Equals メソッドの戻り値を決定するオブジェクトの状態に変更がない限り、一貫して同じハッシュ コードを返す必要があります。これはアプリケーションの現在の実行にのみ当てはまり、アプリケーションが再度実行されると別のハッシュ コードが返される可能性があることに注意してください。

于 2013-04-11T14:39:45.977 に答える