【发布时间】:2020-08-14 03:50:26
【问题描述】:
我有一个电机接口和各种特定于供应商的接口实现。
public interface IMotor
{
void Home();
void Move();
}
public class VenodorAMotor : IMotor
{
public void Home()
{ /*home motor*/ }
public void Move()
{ /*move motor*/ }
}
我正在装饰 IMotor 以向其 home 方法添加一些功能。
public class HomeAdjustmentDecorator : IMotor
{
private IMotor decoratedMtr;
public static explicit operator VendorAMotor(HomeAdjustmentDecorator mtr)
{ return (VendorAMotor)mtr.decoratedMtr; }
public HomeAdjustmentDecorator(IMotor mtr)
{
if(! mtr is VenodorAMotor)
throw new Exception("HomeAdjustmentDecorator can only decorate VenodorAMotor objects");
decoratedMtr = mtr;
}
public void Home()
{
decoratedMtr.Home();
double adjustment = ((VendorAMotor)myMotor).GetHomeAdjustment();//vendor-specific functionality
Log(adjustment);
}
public void Move()
{ decoratedMtr.Move(); }
}
我无法控制 VendorAMotor 的创建,所以我不能轻易使用继承。
问题在于现有代码已经将未修饰的 IMotor 强制转换为其实现类以访问其他供应商特定的功能。转换失败,因为 HomeAdjustmentDecorator 没有继承 VenodorAMotor。
IMotor myDecoratedMotor;//Implementation is HomeAdjustmentDecorator composed of VendorAMotor
...
((VendorAMotor)myDecoratedMotor).DoOtherVendorSpecificStuff();
我尝试过覆盖如图所示的强制转换运算符,但这不起作用。我得到一个 InvalidCastExeption:“无法将 'HomeAdjustmentDecorator' 类型的对象转换为 'VenodorAMotor'。”
一切编译正常。不执行显式转换运算符覆盖,不命中断点。问题是,这个强制转换是否没有执行?
最接近我在这里找到了一个类似的问题: Decoration with several interface 但这并没有太大帮助。
我想答案就在这里: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/conversions#user-defined-conversions 但我认为我遗漏了一些微妙的细节。
【问题讨论】:
-
由于装饰器功能是特定于
VenodorAMotor实现的,您是否可以将必要的代码添加到VenodorAMotor类中? -
假设
myDecoratedMotor是IMotor并且您无法控制IMotor,您无法向其添加转换(只能将转换添加到他们自己的类)...所以你可能想澄清你到底想要达到什么目标,以及你愿意做些什么来达到目标...... -
@AlexeiLevenkov;您能否为我澄清一下您的陈述:“您无法为其添加转换(只能将转换添加到他们自己的班级)”?我正在尝试将
IMotor,实现是HomeAdjustmentDecorator转换为VenodorAMotor,HomeAdjustmentDecorator由IMotor组成(作为IMotor)。我控制“HomeAdjustmentDecorator”并且知道它是由我试图将其投射到的内容组成的。谢谢! -
@user3532473 我没有得到你的评论。根据问题,它听起来像
IMotor myDecoratedMotor;- 你没有机会根据你的限制让演员工作......事实上HomeAdjustmentDecorator myDecoratedMotor...; ((VenodorAMotor)myDecoratedMotor).DoOtherVendorSpecificStuff();可以很好地与你的代码一起工作......但比你想问的更好吗?跨度> -
@AlexeiLevenkov。 ((VenodorAMotor)myDecoratedMotor).DoOtherVendorSpecificStuff();不工作。我想这正是我想问的 - 为什么它不起作用或者我错过了什么?似乎其他未决答案之一可能有它:“转换运算符不适用于接口,因为在编译时,没有具体类型可供(编译器)使用来查找此类运算符。”