Mi cerebro se ha convertido en gelatina, o estoy teniendo una experiencia mental, o algo así. Estoy jugando con una jerarquía de clases que se ve un poco como esto:
Operadores y herencia
Mi clase Money
se ve así:
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);
}
}
Mi Dólar operator *
se ve así:
public static Dollar operator *(Dollar multiplicand, int multiplier)
{
var result = multiplicand.Amount * multiplier;
return new Dollar(result);
}
Ahora, si ejecuto este código de prueba, obtengo un desbordamiento de pila (wahoo!)
{
Money fiveDollars = Money.Dollar(5);
Money timesTwo = fiveDollars*2;
}
Esperaba que esto llamara recursivamente a la subclase (Dollar) operator *
, lo que arrojaría un resultado definitivo ya que (Dollar * int) se define de forma no recursiva. Como esto no funciona, la alternativa es que he hecho algo tonto. ¿Por qué esto no funciona? ¿Cuál sería la forma correcta de obtener este comportamiento?
Cuando obtiene un desbordamiento de pila, debe examinar la pila. Verás las mismas funciones llamándose una y otra vez. Solo eso te dirá mucho sobre lo que está pasando y por qué. – abelenky
Tenga en cuenta que la recursión se produce porque en realidad está invocando 'Money.operator *', no 'Dollar.operator *'. Los operadores están * sobrecargados *, no * reemplazados *, por lo que la función que se invoca está determinada por los tipos * de tiempo de compilación * de los operandos, no por los tipos * de tiempo de ejecución *. Como 'fiveDollars' es una variable de tipo' Money', 'fiveDollars * 2' invoca la versión' Money' de 'operator *' (aunque el tipo * run-time * de 'fiveDollars' es' Dollar'.) – dlev