【问题标题】:Test not compiling - operator overrides in C#测试未编译 - C# 中的运算符覆盖
【发布时间】:2021-12-09 06:04:03
【问题描述】:

我正在使用具有 2 个属性的结构,并且我正在覆盖一些运算符,以便根据它们的“数量”进行比较、加法和减法。

public struct CurrencyAmount
{
    private decimal amount;
    private string currency;

    public CurrencyAmount(decimal amount, string currency)
    {
        this.amount = amount;
        this.currency = currency;
    }

    public static decimal operator +(CurrencyAmount amount1, CurrencyAmount amount2)
    {
        if (amount1.currency != amount2.currency) throw new ArgumentException();
        return amount1.amount + amount2.amount;
    }
    public static decimal operator -(CurrencyAmount amount1, CurrencyAmount amount2)
    {
        if (amount1.currency != amount2.currency) throw new ArgumentException();
        return amount1.amount - amount2.amount;
    }

我的问题是这个测试没有编译:

    [Property]
public void Addition_with_same_currency(decimal value1, decimal value2)
{
    var amount1 = new CurrencyAmount(value1, "HD");
    var amount2 = new CurrencyAmount(value2, "HD");
    var expected = new CurrencyAmount(value1 + value2, "HD");

    Assert.Equal(expected, amount1 + amount2);
}

我收到一个 CS1503 错误:参数 1:无法从“CurrencyAmount”转换为“字符串”和参数 2:无法分别从“预期”和“金额 1 + 金额 2”参数转换为“字符串” .

但是这个测试编译并通过了:

    [Property]
public void Addition_is_commutative(decimal value1, decimal value2)
{
    var amount1 = new CurrencyAmount(value1, "HD");
    var amount2 = new CurrencyAmount(value2, "HD");

    Assert.Equal(amount1 + amount2, amount2 + amount1);
}

所以加法运算符似乎被正确地覆盖了。我在这里错过了什么?

【问题讨论】:

  • 技术要点:您没有 overridden 运算符(而且您不能)。您已经重载它们。 (有机会再看看其他的……)
  • 单独 - 如果您将其简化为最小示例,也会有所帮助。我认为没有使用 ==!=<> 运算符,因此您可以从示例中删除它们。我还认为您的 Equals 方法没有达到您的预期(并且很可能引发 StackOverflow 异常)。
  • expectedCurrencyAmount,其中 amount1 + amount2decimal,因为重载的 operator + 返回 decimal。您可能应该返回 CurrencyAmountreturn new CurrencyAmount(amount1.amount + amount2.amount, amount1.currency);
  • - 运算符计算错误-=
  • 为了简洁起见,我已经编辑了代码

标签: c# overriding operator-keyword assert


【解决方案1】:

amount1 + amount2 返回一个decimal,然后你基本上试图将CurrencyAmount 等同于decimal

我建议让+ 运算符返回一个新的CurrencyAmount

public static CurrencyAmount operator +(CurrencyAmount amount1, 
    CurrencyAmount amount2)
{
    if (amount1.currency != amount2.currency) throw new ArgumentException();
    return new CurrencyAmount(amount1.amount + amount2.amount, amount1.currency);
}

另一种选择是创建一个接受小数的== 运算符,但您会丢失货币类型检查:

public static bool operator ==(CurrencyAmount amount1, decimal amount2)
{
    return (amount1.amount == amount2);
}

public static bool operator !=(CurrencyAmount amount1, decimal amount2)
{
    return (amount1.amount != amount2);
}

现在你可以这样做了:

Assert.True(expected == (amount1 + amount2));

【讨论】:

    【解决方案2】:

    编译失败的原因是Assert.AreEqual 需要两个相同类型的对象。您传递给它的是 CurrencyAmountdecimal,它们是不同的类型。

    虽然 DavidG 的回答是正确的,但有一个更简单的解决方案,尽管它需要您更改 CurrencyAmount.amount 的访问修饰符。无论如何,具有所有私有成员的结构有什么意义?

    我从你的代码中最好的猜测是你想要这样的东西:

       public struct CurrencyAmount
        {
            public decimal Amount { get; }
            public string Currency { get; }
    
            public CurrencyAmount(decimal amount, string currency)
            {
                Amount = amount;
                Currency = currency;
            }
    
            public static decimal operator +(CurrencyAmount amount1, CurrencyAmount amount2)
            {
                if (amount1.Currency != amount2.Currency) throw new ArgumentException();
                return amount1.Amount + amount2.Amount;
            }
            public static decimal operator -(CurrencyAmount amount1, CurrencyAmount amount2)
            {
                if (amount1.Currency != amount2.Currency) throw new ArgumentException();
                return amount1.Amount - amount2.Amount;
            }
        }
    
        [Property]
        public void Addition_with_same_currency(decimal value1, decimal value2)
        {
            var amount1 = new CurrencyAmount(value1, "HD");
            var amount2 = new CurrencyAmount(value2, "HD");
            var expected = new CurrencyAmount(value1 + value2, "HD");
    
            Assert.Equal(expected.Amount, amount1 + amount2);
        }
    

    另外,我认为您将 - 运算符定义为 -= 是一个错字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-29
      相关资源
      最近更新 更多