11

私はいくつかの単体テストを書いていますが、次のアサーションは失敗します:

Assert.AreEqual(expected.Episode, actual.Episode);

代わりにこれを呼び出すと、成功します。

Assert.IsTrue(expected.Episode.Equals(actual.Episode));

この場合、指定されたタイプAssert.AreEqual()のメソッドを最終的に呼び出すと想定していました。Equals()Episode.Equals()

ただし、Microsoft.VisualStudio.TestTools.UnitTesting.Assertの内部で、次のコード(ReSharperによって逆コンパイルされたもの)が見つかりました。

public static void AreEqual<T>(T expected, T actual, string message, params object[] parameters)
{
    if (object.Equals((object)expected, (object)actual))
        return;
    Assert.HandleFail...
}

これは、メソッドが両方をAreEqual()キャストしていることと、クラスで記述したオーバーロードではなく、基本メソッドの使用を強制することを意味します。基本メソッドは、参照が同じであるかどうかを確認するだけですが、そうではありません。expectedactualobjectEquals()Episode

2つの質問があります:

  1. 私の説明は実際に正しいですか、それとも何かを逃したことがありますか?
  2. フレームワークがそのメソッドのオーバーロードではなくobject.Equals()の使用を強制したいのはなぜですか?

関連する場合は、ここに私の方法があります:

public bool Equals(Episode other)
{
    return Number == other.Number &&
           CaseNote.Equals(other.CaseNote) &&
           Patient.Equals(other.Patient);
}
4

2 に答える 2

6

を使用してobject.Equals(object,object)おり、次のような処理を行います。

  • それらは同じ参照ですか?
  • どちらかまたは両方がnull参照ですか?

そしてそれらを処理したx.Equals(y) 、使用を続けます。object それがかかるので、それはobject.Equals(object,object)それらをキャストする必要があります。にキャストすると、 (通常のボックス化されたボックスへのボックスまたは通常のボックス化されたボックスへの)objectいくつかの複雑さも回避されます。Nullable<T>T?nullT

ただし、次のように実装することもできます。

 if (EqualityComparer<T>.Default.Equals(expected,actual))
    return;

これは、、、vs 、Nullable<T>およびボクシングなしで他のいくつかのシナリオを処理します。IEquatable<T>structclass

しかし:現在の実装はその役割を果たしており、時折のボックスは世界の終わりではありません(そして:あなたのタイプがである場合、ボクシングは問題ではありませんclass)。

于 2012-11-14T14:30:02.140 に答える
4

コードではEquals(object other)、同様にオーバーライドする必要があります(GetHashCodeもオーバーライドする必要があります)。

これをコードに追加するだけです

public bool Equals(Episode other)
{
    return Number == other.Number &&
           CaseNote.Equals(other.CaseNote) &&
           Patient.Equals(other.Patient);
}

public override bool Equals(object other)
{
    Episode castOther = other as Episode;
    if(castOther == null)
        return false;
    return this.Equals(castOther);
}

public override int GetHashCode()
{
    //TODO: Implement using the members you used in "Equals(Episode other)"
    throw new NotImplmentedExecption();
}

GetHashCodeについては、2つのオブジェクトが等しい場合、それらも等しいハッシュコードを返す必要があることを忘れないでください。これは、視覚化に役立つ簡単な図です。

ここに画像の説明を入力してください

同様の問題CaseNoteを確認することをお勧めします。Patient

于 2012-11-14T15:10:12.223 に答える