1

テスト時に、次のような呼び出しを使用してこれらのオブジェクトのコレクションをIEquatable<T>簡単に比較できるように、実装したクラスがあります。IEnumerable

Assert.IsTrue(expected.SequenceEqual(actual));

これは現在うまく機能していますが、いくつかのしつこい疑問があります。クラスは次のようになります。

public class ThirdPartyClaim : IEquatable<ThirdPartyClaim>
{
    // fields removed for question

    public bool Equals(ThirdPartyClaim compareTo)
    {
        if (object.ReferenceEquals(this, compareTo))
        {
           return true;
        }

        return this.ClaimId.Equals(compareTo.ClaimId) && 
               this.Firstname.Equals(compareTo.Firstname) &&
               this.Lastname.Equals(compareTo.Lastname);
    }

   public override int GetHashCode()
   {      
        int hashClaimId = this.ClaimId == null ? 0 : this.ClaimId.GetHashCode();
        int hashFirstname = this.Firstname == null ? 0 : this.Firstname.GetHashCode();
        int hashLastname = this.Lastname == null ? 0 : this.Lastname.GetHashCode();

        return hashClaimId ^ hashFirstname ^ hashLastname;
    }

をオーバーライドすることについての私の理解はGetHashCode()、クラスの同じインスタンスを指すオブジェクトを比較するために使用されるということです。この機会にこれが必要になる可能性は非常に低いです (将来的にも)。

この理解は正しいですか? もしそうなら、コードを安全に削除できますか?

単体テストでこれらのオブジェクトのコレクションを比較するより良い方法はありますか?

私は MSTest を使用するように制約されていますが。

タンス

4

1 に答える 1

4

GetHashCodeをオーバーライドする場合はオーバーライドが必要ですEquals。そうしないと、ハッシュベースのコンテナーが正しく機能しない可能性があります。のドキュメントからObject.Equals:

Equals をオーバーライドする型は、GetHashCode もオーバーライドする必要があります。そうしないと、Hashtable が正しく機能しない可能性があります。

あなたのケースではコードが実行されないかもしれませんが、とにかくそれを保持する必要があります。正しいことに加えて、シーケンスに関係なくコレクションの同等性をテストするのに役立ちます。

Assert.IsTrue(expected.Except(actual).Count() == 0);    

実装に加える変更の 1 つGetHashCodeは、その対称性を排除することです。現在、オブジェクト内の姓名を切り替えると、同じハッシュ コードが作成されます。これは準最適です。int次のように、複数の s int を小さな素数 (31 など) で乗算し、それらを合計することで、ハッシュ コード内で組み合わせることができます。

public override int GetHashCode()
{      
    int hashClaimId = this.ClaimId == null ? 0 : this.ClaimId.GetHashCode();
    int hashFirstname = this.Firstname == null ? 0 : this.Firstname.GetHashCode();
    int hashLastname = this.Lastname == null ? 0 : this.Lastname.GetHashCode();

    return 31*31*hashClaimId + 31*hashFirstname ^ hashLastname;
}
于 2013-05-15T10:19:10.537 に答える