2012-11-14 70 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

感謝您的有用答案。我知道這是* *其實,我的代碼返回了兩個斷言不同的結果的原因。 –

相關問題