c# - 为什么 Assert.AreEqual() 在比较之前转换为对象?

标签 c# .net unit-testing assert

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

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() 方法正在将 expectedactual 转换为 object 到强制使用基本 Equals() 方法,而不是我在 Episode 类中编写的重载。基本方法将简单地检查引用是否相同,如果它们不相同。

我有两个问题:

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

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

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

最佳答案

它正在使用 object.Equals(object,object) ,它处理类似的事情:

  • 它们是同一个引用吗?
  • 是一个或两个都是 null 引用?

then 在处理完这些事情后 继续使用 x.Equals(y)。它必须将它们转换为 object 因为这是 object.Equals(object,object) 需要的。强制转换为 object 也避免了 Nullable<T> 的一些复杂情况(因为 T? 要么是 null 要么是常规的盒装 T)。

但是,它也可以实现为:

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

它处理 Nullable<T>IEquatable<T>structclass 以及其他一些没有任何装箱的场景。

但是:当前的实现可以完成这项工作,偶尔出现的框并不是世界末日(而且:如果您的类型是 class,装箱甚至不是问题)。

关于c# - 为什么 Assert.AreEqual() 在比较之前转换为对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13380557/

相关文章:

c# - 区分用户交互引发的事件和我自己的代码

c# - 创建和验证邀请码/ token

.net - 使用 Microsoft graph api sdk 订阅用户状态

WCF 序列化单元测试和此 XmlWriter 不支持 base64 编码数据。我应该使用什么 Writer?

c# - 使用 Moq 部分模拟类内部方法

c# - 文本框属性

c# - WPF ComboBox : Trouble converting back-and-forth of Selected Item (Works in all cases, 但就是这个。)

c# - 使用 WebAdministration 管理单元从 .NET 运行 Powershell 脚本

vb.net - vb.net 项目的单元测试

c# - 在 WPF 中处理来自 Winforms 组件的未处理异常