6

参照型に Equals() を実装するのは、思ったより難しいです。私の現在の正規の実装は次のようになります。

public bool Equals( MyClass obj )
{
  // If both refer to the same reference they are equal.
  if( ReferenceEquals( obj, this ) )
    return true;

  // If the other object is null they are not equal because in C# this cannot be null.
  if( ReferenceEquals( obj, null ) )
   return false;

   // Compare data to evaluate equality    
   return _data.Equals( obj._data );
}

public override bool Equals( object obj )
{
  // If both refer to the same reference they are equal.
  if( ReferenceEquals( obj, this ) )
    return true;

  // If the other object is null or is of a different types the objects are not equal. 
  if( ReferenceEquals( obj, null ) || obj.GetType() != GetType() )
    return false;

  // Use type-safe equality comparison
  return Equals( (MyClass)obj );
}

public override int GetHashCode()
{
  // Use data's hash code as our hashcode  
  return _data.GetHashCode();
}

これはすべてのコーナー(継承など)のケースをカバーしていると思いますが、間違っているかもしれません。皆さんはどう思いますか?

4

6 に答える 6

4

しばらく前に、これに関するかなり包括的なガイドを書きました。まず、equals の実装を共有する必要があります (つまり、オブジェクトを受け取るオーバーロードは、厳密に型指定されたオブジェクトを受け取るオーバーロードにパススルーする必要があります)。さらに、GetHashCode をオーバーライドする必要があるため、オブジェクトを不変にするなどのことを考慮する必要があります。詳細はこちら:

http://gregbeech.com/blog/implementing-object-equality-in-dotnet

于 2008-09-16T17:27:11.207 に答える
1

参照型でもある場合は、 this._data が null でないことを願っています。

public bool Equals( MyClass obj )
{
    if (obj == null) {
        return false;
    }
    else {
        return (this._data != null && this._data.Equals( obj._data ))
                         || obj._data == null;
    }
}

public override bool Equals( object obj )
{
    if (obj == null || !(obj is MyClass)) {
        return false;
    }
    else {
        return this.Equals( (MyClass)obj );
    }
}

public override int GetHashCode() {
    return this._data == null ? 0 : this._data.GetHashCode();
}
于 2008-09-16T17:22:54.757 に答える
0

chakrit に同意します。異なるタイプのオブジェクトが同じデータまたは ID を持っている場合、意味的に同等であることを許可する必要があります。

個人的には、以下を使用しています。

    public override bool Equals(object obj)
    {
        var other = obj as MyClass;
        if (other == null) return false;

        return this.data.Equals(other.data);
    }
于 2008-09-16T17:17:09.747 に答える
0

値型と参照型のどちらを書いているかによって異なります。並べ替え可能な値の型については、次のことをお勧めします: フレームワーク デザイン ガイドラインに準拠したスケルトン値の型を実装する Visual Studio 2005 のコード スニペット

于 2008-09-16T16:59:02.410 に答える
0

継承に関しては、OO パラダイムに魔法をかけてもらうべきだと思います。

具体的には、GetType()チェックを削除する必要があります。ポリモーフィズムが崩壊する可能性があります。

于 2008-09-16T17:01:02.297 に答える