【发布时间】:2023-04-02 08:11:01
【问题描述】:
我的大脑变成了果冻,或者我有一种精神错乱的经历,或者其他什么。我正在修改一个看起来有点像这样的类层次结构:
我的Money 类如下所示:
public abstract class Money
{
public int Amount { get; set; }
public static bool operator ==(Money leftSide, Money rightSide)
{
// Money can only be equal if it is in the same currency.
if (leftSide.GetType() != rightSide.GetType()) return false;
return leftSide.Amount == rightSide.Amount;
}
public static bool operator !=(Money leftSide, Money rightSide)
{
// If the currencies are different, the amounts are always considered unequal.
if (leftSide.GetType() != rightSide.GetType()) return true;
return leftSide.Amount != rightSide.Amount;
}
public static Money operator *(Money multiplicand, int multiplier)
{
var result = multiplicand * multiplier;
return result;
}
public static Dollar Dollar(int amount)
{
return new Dollar(amount);
}
public static Franc Franc(int amount)
{
return new Franc(amount);
}
}
我的美元operator * 看起来像这样:
public static Dollar operator *(Dollar multiplicand, int multiplier)
{
var result = multiplicand.Amount * multiplier;
return new Dollar(result);
}
现在,如果我运行这个测试代码,我会得到一个堆栈溢出(哇哦!)
{
Money fiveDollars = Money.Dollar(5);
Money timesTwo = fiveDollars*2;
}
我原以为这会递归调用子类 (Dollar) operator *,这将返回一个确定的结果,因为 (Dollar * int) 是非递归定义的。由于这不起作用,另一种选择是我做了一些愚蠢的事情。为什么这不起作用?获得这种行为的正确方法是什么?
【问题讨论】:
-
当您遇到堆栈溢出时,您应该检查堆栈。您会看到相同的函数一遍又一遍地相互调用。仅此一项就可以告诉您很多有关发生的事情和原因的信息。
-
请注意,发生递归是因为您实际上是在调用
Money.operator*,而不是Dollar.operator*。运算符是重载,而不是覆盖,因此调用的函数由操作数的编译时类型决定,而不是运行时类型。由于fiveDollars是Money类型的变量,所以fiveDollars * 2调用operator*的Money版本(即使fiveDollars的run-time 类型是Dollar。 )
标签: c# oop architecture operator-overloading