2014-03-19 43 views
4

鑑於此代碼段int - > sbyte - > sbyte的顯式轉換?

[TestMethod] 
public void SByte() 
{ 
int integerValue = -129; 
sbyte sbyteValueFromInt = (sbyte) integerValue; 
Assert.AreEqual(sbyteValueFromInt, 127); // True 

byte byteValue = (byte) integerValue; 
sbyte sbyteValueFromByte= (sbyte) byteValue; 
Assert.AreEqual(sbyteValueFromByte, 127); // True 

sbyte? nullableSbyte = sbyteValueFromByte; 
Assert.AreEqual(nullableSbyte.Value, 127); // True 
Assert.AreEqual((sbyte)nullableSbyte, 127); // True 
Assert.AreEqual(nullableSbyte, 127); // Assert.AreEqual failed. Expected:<127 (System.SByte)>. Actual:<127 (System.Int32)>. 
} 

爲什麼最後斷言失敗了嗎?

如果我們深入探討MSTestAreEqual<object>那麼它不應該認出127轉換爲sbyte?

Assert.AreEqual<object>(expected, actual, message, parameters); 

public static void AreEqual<T>(T expected, T actual, string message, params object[] parameters) 
{ 
message = Assert.CreateCompleteMessage(message, parameters); 
if (object.Equals((object) expected, (object) actual)) 
    return; 
Assert.HandleFailure ... 
} 

怎麼來的不知道怎麼投127sbyte但它確實給sbyte?

+0

@ SudhakarTillapudi'nullableSbyte.Value'是'sbyte '。 'nullableSbyte'是'sbyte?'。 –

回答

2

這似乎是一個錯誤 MSTest的功能。當使用NUnit重複測試或僅使用operator ==時,隱式轉換得到遵守。

的MSTest的斷言歸結爲:

Assert.AreEqual<object>(expected, actual, message, parameters); 

public static void AreEqual<T>(T expected, T actual, string message, params object[] parameters) 
{ 
    message = Assert.CreateCompleteMessage(message, parameters); 
    if (object.Equals((object) expected, (object) actual)) 
    return; 
    Assert.HandleFailure ... 
} 

過早拳擊通過object可能是罪魁禍首。

爲了解決這個問題,你有明顯的陳述到MSTest的狀態和T爲其提供明確的,即:

Assert.AreEqual<sbyte?>(nullableSbyte, 127); 

,然後通過。

相比之下,NUnit的斷言通過沒有任何幫助:

[Test] 
    public void SByte() 
    { 
     sbyte? nullableSbyte = sbyteValueFromByte; 
     Assert.AreEqual(nullableSbyte.Value, 127); // True 
     Assert.AreEqual(nullableSbyte, 127); 
    } 

由於做了,窮人的單元測試:

sbyte? nullableSbyte = sbyteValueFromByte; 
    if (nullableSbyte.Value != 127) 
    { 
     throw new Exception("Not Equal"); 
    } 
    if (nullableSbyte != 127) 
    { 
     throw new Exception("Not Equal"); 
    } 

編輯

R# comparison

+0

如果'object'是罪魁禍首,通過'boxing'和'unboxing',它不應該遵守C#規範中的Explicit nullable conversion嗎? '從S到T的明確轉換?' –

+0

我已經用R#粘貼了屏幕截圖 - 看起來盒裝比較只有在127被轉換爲sbyte後才能被裝箱。 – StuartLC

+0

如果我做'Assert.AreEqual((object)nullableSbyte.Value,(object)127);',R#也說'類型轉換是多餘的'。如果我們深入研究'AreEqual ',那麼它不應該認識到'127'轉換爲'sbyte'?它怎麼會不知道怎麼把'127'變成'sbyte?',但它做到了'sbyte'? –

相關問題