![](/img/trans.png)
[英]How can a method in a base class return a more derived object based on the type of the object it is called on?
[英]How to create a derived object based on base type only?
例如,我有此类:
public abstract class Device
{
public Device()
{
}
public Device(XmlDevice xmlDevice)
{
// creating device by xmlDevice
}
}
public class Modem : Device
{
public Modem()
{
}
public Modem(XmlModem modem)
{
// creating modem by xmlModem
}
}
public class Plc : Device
{
public Plc()
{
}
public Plc(XmlPlc plc)
{
// creating plc by xmlPlc
}
}
public abstract class XmlDevice
{
public XmlDevice()
{
}
}
public class XmlModem : XmlDevice
{
public XmlModem()
{
}
}
public class XmlPlc : XmlDevice
{
public XmlPlc()
{
}
}
我有一个包含XmlDevice对象的列表-如何根据其类型创建Device对象? 我可以这样:
foreach( xmlDevice in xmlDevicesList )
{
if( xmlDevice is XmlModem )
devicesList.Add( new Modem((XmlModem)xmlDevice) );
else if( xmlDevice is XmlPlc )
devicesList.Add( new Plc((XmlPlc)xmlDevice) );
}
但是我想避免“ is”语句和强制转换对象。 这样做更干净吗?
您对当前实现的厌恶是有充分根据的。 我可以保证,添加新设备类型的时间会很紧。 更糟糕的是,编译器无法知道您希望实例类型检查是详尽无遗的,因此无法通过发出错误信号来帮助您。
如果可以更改Xml*
类,则可以在XmlDevice
简单地引入一个抽象方法CreateDevice
,并在派生类中重写它:
public abstract class XmlDevice
{
// ...
public abstract Device CreateDevice();
// ...
}
public class XmlModem : XmlDevice
{
// ...
public override Device CreateDevice()
{
return new Modem(this);
}
// ...
}
现在,您可以简单地执行以下操作:
devicesList = xmlDevicesList.ConvertAll(x => x.CreateDevice());
也许这种方法的最大好处是,如果不实现CreateDevice
方法,编译器将无法让您摆脱创建新设备类型的CreateDevice
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.