加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 为什么具有隐式转换运算符的自定义结构上的Assert.AreEqua

发布时间:2020-12-15 08:12:09 所属栏目:百科 来源:网络整理
导读:我创建了一个表示金额的自定义结构.它基本上是十进制的包装器.它有一个隐式转换运算符,可将其强制转换为十进制. 在我的单元测试中,我断言Amount等于原始十进制值,但测试失败. [TestMethod]public void AmountAndDecimal_AreEqual(){ Amount amount = 1.5M; A
我创建了一个表示金额的自定义结构.它基本上是十进制的包装器.它有一个隐式转换运算符,可将其强制转换为十进制.

在我的单元测试中,我断言Amount等于原始十进制值,但测试失败.

[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,而小数值1.5M则不是.

我不明白为什么会这样.我本来希望恰恰相反.第一个单元测试应该能够将小数转换为金额.

当我向int添加隐式转换(这没有意义)时,第二个单元测试也会失败.因此,添加隐式强制转换运算符会破坏单元测试.

我有两个问题:

>这种行为的解释是什么?
>如何修复Amount结构,以便两个测试都成功?

(我知道我可以改变测试做一个明确的转换,但如果我不是绝对必须,我不会)

我的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;
    }
}

解决方法

当你可以在两个方向隐式转换时会发生不好的事情,这就是一个例子.

由于隐式转换,编译器能够选择Assert.AreEqual< decimal>(1.5M,amount);和Assert.AreEqual< Amount>(1.5M,金额);价值相等.*

由于它们是相同的,所以推理都不会引起过载.

由于通过推理没有重载选择,因此无法将其放入列表中以选择最佳匹配,并且只有(对象,对象)表单可用.所以这是挑选的.

使用Assert.AreEqual(1,amount)然后由于存在从int到Amount的隐式转换(通过隐式int-> decimal)但没有从Amount到int的隐式转换,编译器认为“显然它们意味着Assert.AreEqual< Amount> ;()这里“?,所以它被选中了.

您可以使用Assert.AreEqual< Amount>()或Assert.AreEqual< decimal>()显式选择重载,但是如果可能的话,您可能最好使其中一个“缩小”必须是明确的因为你的结构的这个功能会再次伤害你. (华友世纪为单位测试发现缺陷).

*另一个有效的重载选择是选择Assert.AreEqual< object>,但它永远不会被推理选择,因为:

>被拒绝的超载都被认为更好.
>无论如何,它始终被非泛型形式所取代.

因此,只能通过包含< object>来调用它.在代码中.

?编译器将对其说的所有内容都视为含义明显或完全不可理解.也有人这样.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读