我已經創建了一個自定義結構來表示一個金額。它基本上是圍繞decimal
的包裝。它有一個隱式轉換運算符,將其轉換回decimal
。爲什麼具有隱式轉換運算符的自定義結構上的Assert.AreEqual失敗?
在我的單元測試中,我聲稱金額等於原始的十進制值,但測試失敗。
[TestMethod]
public void AmountAndDecimal_AreEqual()
{
Amount amount = 1.5M;
Assert.AreEqual(1.5M, amount);
}
當我使用雖然一個int(對此我沒有創建一個轉換操作符),測試不成功。
[TestMethod]
public void AmountAndInt_AreEqual()
{
Amount amount = 1;
Assert.AreEqual(1, amount);
}
當我將鼠標懸停在AreEqual
,這表明第一個解析爲
public static void AreEqual(object expected, object actual);
,第二個導致
public static void AreEqual<T>(T expected, T actual);
它看起來像int
價值1
是隱式投到Amount
,而decimal
值1.5M
不是。
我不明白爲什麼會發生這種情況。我會期望恰恰相反。第一次單元測試應該能夠將decimal
轉換爲Amount
。
當我向int
添加一個隱式轉換(這沒有意義)時,第二個單元測試也失敗。因此,添加一個隱式投射運算符會打破單元測試。
我有兩個問題:
- ,這是什麼行爲,如何解釋呢?
- 如何修復
Amount
結構,以便兩個測試都能成功?
(我知道我可以改變測試做一個明確的轉換,但如果我沒有絕對要,我不會)
我金額結構(只是最低限度的實施顯示問題)
public struct Amount
{
private readonly decimal _value;
private Amount(decimal value)
{
_value = value;
}
public static implicit operator Amount(decimal value)
{
return new Amount(value);
}
public static implicit operator decimal(Amount amount)
{
return amount._value;
}
}
您的兩個操作符都是「隱式」的。那麼,它應該是'AreEqual'還是'AreEqual '? –
PetSerAl
@PetSerAl是對的。如果你使用'AreEqual'或'AreEqual '它會通過。 –
Nkosi