例如我有这个类:
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”语句和强制转换对象。这样做更干净吗?
答案 0 :(得分:4)
您对当前实施的厌恶是有根据的。我可以向你承诺,它会在你添加新设备类型的那一刻打破。更糟糕的是,编译器无法知道您希望实例类型检查是详尽无遗的,因此不会通过发出错误信号来帮助您。
如果您可以更改Xml*
类,则只需在CreateDevice
中引入抽象方法XmlDevice
,并在派生类中重写它:
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
方法的情况下创建新设备类型。