19

ページング データを無視して、ModelData を返すだけの IEnumerable を実装する PagedModel クラスがあります。また、Equals と GetHashCode をオーバーライドして、2 つの PagedModel オブジェクトを ModelData、PageNumber、TotalPages、および PageSize で比較できるようにしました。

ここに問題があります

Dim p1 As New PagedModel() With {
    .PageNumber = 1,
    .PageSize = 10,
    .TotalPages = 10,
    .ModelData = GetModelData()
}

Dim p2 As New PagedModel() With {
    .PageNumber = 1,
    .PageSize = 10,
    .TotalPages = 10,
    .ModelData = GetModelData()
}

p1.Equals(p2) =====> True
Assert.AreEqual(p1, p2) ======> False!

NUnit は、私が提供した Equals メソッドを使用する代わりに、PagedModel を比較するために内部の EnumerableEqual メソッドを呼び出しているようです! この動作をオーバーライドする方法はありますか、それともカスタム アサーションを作成する必要がありますか。

4

2 に答える 2

12

あなたが求めていることをする:私はそれに対してアドバイスしますが、NUnitの動作が本当に気に入らず、アサーションをカスタマイズしたい場合は、独自のEqualityComparerを提供できます。

Assert.That(p1, Is.EqualTo(p2).Using(myCustomEqualityComparer));

何をすべきか (短い答え) : PagedModel をコレクションとして使用し、ModelData を要素として使用しているため、PagedModel の代わりに ModelData に GetHashCode と equals が必要です。

何をすべきか (長い答え) : PagedModel でEquals(object)をオーバーライドする代わりに、 ModelData でIEquatable<T>を実装する必要があります。ここで、 T は IEnumerable の型パラメーターであり、GetHashCode()をオーバーライドします。これらの 2 つのメソッドは、.Net のすべての IEnumerable メソッドが、既定の等値比較ツール (独自のIEqualityComparerを指定しない) を使用するときに (Union、Distinct などの操作に対して) 等値を判断するために使用するものです。

[Default Equality Comparer] は、型 T が System.IEquatable インターフェイスを実装しているかどうかをチェックし、そうであれば、その実装を使用する EqualityComparer を返します。それ以外の場合は、T によって提供される Object.Equals および Object.GetHashCode のオーバーライドを使用する EqualityComparer を返します。


正しく機能するために、GetHashCode は、.Equals(T) に対して true を返すすべてのオブジェクトに対して同じ結果を返す必要があります。逆は必ずしも真ではありません - GetHashCode は、等しくないオブジェクトの衝突を返す可能性があります。詳細はこちら - Marc Gravel の受け入れられた回答を参照してください。また、素数を使用したその回答の GetHashCode の実装が非常に便利であることもわかりました。

于 2012-05-29T22:05:28.927 に答える