Во-первых, это назначение не является законным:
Coffee coffee = new Mocha(new Coffee());
A Mocha
не является Coffee
, и при этом не существует неявного приведения от Mocha
к Coffee
. Чтобы «удалить» декоратор, вам нужно предоставить либо метод, либо приведение для этого. Таким образом, вы можете добавить неукрашенный метод к Mocha
:
public Coffee Undecorate() {
return (Coffee)decoratedItem;
}
Тогда вы могли бы сказать
Coffee coffee = new Mocha(new Coffee()).Undecorate();
В качестве альтернативы, вы можете предоставить неявный оператор приведения в классе Mocha
:
public static implicit operator Coffee(Mocha m) {
return (Coffee)m.decoratedItem;
}
Тогда твоя линия
Coffee coffee = new Mocha(new Coffee());
будет законным.
Теперь ваш вопрос предполагает потенциальное неправильное понимание шаблона проектирования (и, фактически, ваша реализация также предлагает такой вариант). То, что ты пытаешься сделать, очень вонючее. Правильный способ использования шаблона декоратора такой. Обратите внимание, что CoffeeDecorator
происходит от Coffee
!
abstract class Item { public abstract decimal Cost(); }
class Coffee : Item { public override decimal Cost() { return 1.99m; } }
abstract class CoffeeDecorator : Coffee {
protected Coffee _coffee;
public CoffeeDecorator(Coffee coffee) { this._coffee = coffee; }
}
class Mocha : CoffeeDecorator {
public Mocha(Coffee coffee) : base(coffee) { }
public override decimal Cost() { return _coffee.Cost() + 2.79m; }
}
class CoffeeWithSugar : CoffeeDecorator {
public CoffeeWithSugar(Coffee coffee) : base(coffee) { }
public override decimal Cost() { return _coffee.Cost() + 0.50m; }
}
Тогда вы можете сказать:
Coffee coffee = new Mocha(new CoffeeWithSugar(new Coffee()));
Console.WriteLine(coffee.Cost()); // output: 5.28
Учитывая это, для чего вам нужен декор?