2014-01-27 18 views
1

我在編寫新的單元測試時遇到了一些問題。我在代碼示例中的註釋解釋了我的具體問題:初始化變量時使用新內存位置的條件是什麼?

KeyboardLayout layout 
    = Engine.ParseLayout(Dimensions.Create(300, 300), "FooBar", provider); 
var dweeb = layout.Layout.SelectMany(t => t); 

//Parsed layout is not a mutant 
Assert.IsTrue(!layout.IsMutant); 

KeyboardLayout newLayout = StandardKeyboardMutations.MutateKeyboard(layout); 

var newb = newLayout.Layout.SelectMany(t => t); 

//I don't understand why this test fails. They should be stored in seperate memeory locations and therefore not equal by reference comparison. 
//Unless of course saying var x = foo doesn't always provide a fresh memory location for the value of foo. 
Assert.AreNotEqual(layout, newLayout); 

此行Assert.AreNotEqual(layout, newLayout);總是失敗。

我不知道爲什麼我一直在做這個假設(在評論中指出)直到現在:聲明一個變量總是執行一個存儲過程到一個新的內存位置。 (一個沒有被當前正在運行的程序使用)。

要清楚,問題是,在c#中,var x = foo;總是使用新的存儲單元嗎?如果不是,使用一個標準是什麼?或者它可能總是在x中存儲值的地址?或者我錯過了一些東西,並且我完全錯誤地提出了錯誤的問題,以發現這裏出了什麼問題?

這是我第一次「官方」單元測試經驗,提前致謝。

+0

我找不到有關'StandardKeyboardMutations'的任何文檔。你有參考嗎? –

+0

自定義類。如果你想看看它的實現,我不得不想出一個不同的例子。 – gordlonious

+0

答案可能在於它的實現。除非你重寫'KeyboardLayout.Equals',否則你會得到'ReferenceEquals'實現。這意味着某種方式'StandardKeyboardMutations。MutateKeyboard'正在返回一個對'*'和'layout'相同的對象的引用 - 可能*不是*你想要的。 –

回答

3

您正在尋找Assert.AreSame而不是Assert.AreEqual

Assert.AreSame()斷言檢查該參數引用相同的對象(你所提到的「同一存儲器位置」),而Assert.AreEqual()(分別AreNotEqual()),用於底層的對象的相等,即斷言檢查時,它檢查該a.Equals(b),即使ab引用不同的對象,它也可以成立。

+0

這是很好的信息。但是,我使用了Assert.AreNotSame();方法和斷言仍然失敗。儘管我的示例代碼讓我相信,但它們必須引用相同的對象。 – gordlonious

+0

如果它們仍然是相同的,那麼'StandardKeyboardMutations'可能會利用[Flyweight模式](http://en.wikipedia.org/wiki/Flyweight_pattern)來分享它實現的突變。如果你能擴大這個問題來包含所述的實現或其相關部分,那將是最好的。 – mockinterface

2

確實var x = foo;總是使用新的記憶細胞?

是的,x總是新的記憶和平。然而,這並不意味着你認爲它的意思。

或者,也許它總是在x存儲value的地址?

是的,如果value類型是引用類型。例如

var x = new MyClass(); 
var y = x; 

兩個xy包含引用(你可以把它作爲一個地址),以相同的內存和平,其中MyClass()例如實際存儲。

對於值類型,這是完全不同的:當分配給y

var x = new MyStruct(); 
var y = x; 

整個對象被複制。沒有參考,對象本身存儲在y

+0

我懷疑OP實際上需要別的東西。但良好的開端:)優化和各種別名2種變量共享內存位置,拳擊...簡單鏈接到Eric Lipperts博客[Value types](http://blogs.msdn.com/b/ericlippert/ archive/2010/09/30/the-truth-about-value-types.aspx)可能已經足夠了...... –

+0

所以,你會說在我的示例代碼中,如果dweeb和newb在右手邊都有引用類型初始化=他們可能引用相同的東西? – gordlonious

+0

我不這麼認爲,他們引用LINQ內存中的查詢定義。你平等的原因是因爲你使用錯誤的'Assert'方法(如其他答案所述)。 – MarcinJuraszek

相關問題