为什么在比较之前将Assert.AreEqual()强制转换为对象?

Sir*_*lot 11 .net c# unit-testing assert

我正在编写一些单元测试,以下断言失败:

Assert.AreEqual(expected.Episode, actual.Episode);
Run Code Online (Sandbox Code Playgroud)

如果我改为调用它,它会成功:

Assert.IsTrue(expected.Episode.Equals(actual.Episode));
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我假设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...
}
Run Code Online (Sandbox Code Playgroud)

这意味着我的AreEqual()方法是铸造既expectedactualobject强制使用基本的Equals()方法,而不是我写的超载Episode类.基本方法只是检查引用是否相同,它们不是.

我有两个问题:

  1. 我的解释是否正确,还是我错过了什么?
  2. 为什么框架要强制使用object.Equals()而不是该方法的重载?

如果它是相关的,这是我的方法:

public bool Equals(Episode other)
{
    return Number == other.Number &&
           CaseNote.Equals(other.CaseNote) &&
           Patient.Equals(other.Patient);
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 6

它正在使用object.Equals(object,object),它涉及以下内容:

  • 他们是同一个参考?
  • 是一个或两个null参考?

继续使用x.Equals(y) 后,它已处理这些事情.它必须将它们投射到,object 因为这是object.Equals(object,object)需要的.铸造object也避免了一些并发症Nullable<T>(因为一个T?盒子要么null是普通的盒装T).

但是,它也可以实现为:

 if (EqualityComparer<T>.Default.Equals(expected,actual))
    return;
Run Code Online (Sandbox Code Playgroud)

它处理Nullable<T>,IEquatable<T>,structVS class,以及一些其他情况没有任何拳击.

但是:当前的实现完成了这项工作,并且偶尔的盒子不是世界末日(并且:如果你的类型是a,拳击甚至不是问题class).