2

For example I have this classes:

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()
    {
    }
}

I have a list with XmlDevice objects - how can I create Device objects based on its type? I can do this like this:

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) );
}

But I want to avoid "is" statement and casting objects. Is it more clean way to do this?

Bero
  • 990
  • 7
  • 12

1 Answers1

4

Your aversion to your current implementation is well-founded. I can promise you it's going to break the minute you add a new device type. What's worse, the compiler has no way of knowing that you intended the instance type check to be exhaustive, and therefore won't help you by signalling an error.

If you can change the Xml* classes, you could simply introduce an abstract method CreateDevice in XmlDevice, and override it in the derived classes:

public abstract class XmlDevice
{
    // ...
    public abstract Device CreateDevice();
    // ...
}

public class XmlModem : XmlDevice
{
    // ...
    public override Device CreateDevice()
    {
        return new Modem(this);
    }
    // ...
}

Now you can simply do this:

devicesList = xmlDevicesList.ConvertAll(x => x.CreateDevice());

Perhaps the greatest benefit of this approach is that the compiler won't let you get away with creating a new device type without implementing the CreateDevice method.

Martin Törnwall
  • 9,299
  • 2
  • 28
  • 35