2012-11-14 31 views
11

我正在写一些单元测试及以下断言失败:为什么在比较之前将Assert.AreEqual()强制转换为对象?

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()方法既铸造expectedactualobject强制使用基地Equals()方法,而不是我写在Episode类中的超负荷。基本方法将简单地检查引用是否相同,哪些不是。

我有两个问题:

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

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

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

Offtopic:其中ReSharper的版本可以反编译? – sll

+0

我不知道它已经有多久,但至少V5在我的经验......你第一次F12(去申报)内部的物体上,它会问你想要做什么;其中一个选项是反编译。 Jetbrains还提供免费的独立反编译器。顺便说一句 –

+1

,示出的方法是一个过载* *,而不是一个'override'。 –

回答

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; 

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

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

+0

请注意[通过在'Nullable '上对对象进行空值检查可以避免性能影响](http://stackoverflow.com/q/12396457/50776)(这不是你的错,请记住你)。 – casperOne

+0

@casperOne确实,这就是为什么*如果我正在写它*我会使用'EqualityComparer ',**不会遭受这种情况。 –

+0

虽然这个答案是正确的,它无法解释为什么OP是看到假的时候,他希望看到真实的。这里的主要问题是他只实现了“Equals(Episode other)”而不是“Equals(object other)”。 – Servy

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如果两个对象是相等的,他们必须等于返回哈希码。以下是帮助可视化的快速图表。

enter image description here

您可能要检查CaseNotePatient了类似的问题。

+0

感谢您的有用答案。我知道这是* *其实,我的代码返回了两个断言不同的结果的原因。 –

相关问题