Prasanth V J
Prasanth V J

Reputation: 1196

Deserialize a class with interface

I have a class which contain an interface member variable.How can i deserialize this class

interface ISensor { }

[Serializable]
class Sensor: ISensor { }

[Serializable]
class Root
{
    [XmlElement("Sensor")]
    public List<ISensor> SensorList{ get; set; }
}

My XML will be like this

  <?xml version="1.0" encoding="us-ascii"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Sensor >
        <SensorName>Name1</SensorName>
        <SensorValue>0.0</SensorValue>
    </Sensor>
    <Sensor>
        <SensorName>Name2</SensorName>
        <SensorValue>148.00</SensorValue>
    </Sensor>
</Root>

Upvotes: 1

Views: 6058

Answers (1)

akton
akton

Reputation: 14376

Assuming you are using XmlSerializer, there are two changes required for both serialization and deserialization:

  1. Tell the serializer the list of types that can appear, in other words the types that inherit from Sensor.
  2. Use a class for the List rather than an interface, in other words replace List<ISensor> with List<Sensor>.

Unfortunately, the XmlSerializer does not handle interfaces in the way you want. See XmlSerializer serialize generic List of interface for more information.

If using a base class is not an option You could write your own XML serializer by implementing IXmlSerializable. Override ReadXml and parse the XML manually.

For example:

public interface ISensor { }

[Serializable]
public class Sensor : ISensor { }

[Serializable]
public class Root
{
    // Changed List<ISensor> to List<Sensor>. I also changed
    // XmlElement to XmlArray so it would appear around the list.       
    [XmlArray("Sensor")]
    public List<Sensor> SensorList { get; set; }
}

[Serializable]
public class SensorA : Sensor
{
    [XmlElement("A")]
    public string A { get; set; }
}

[Serializable]
public class SensorB : Sensor
{
    [XmlElement("B")]
    public string B { get; set; }
}

class Program
{
    public static void Main(string[] args)
    {
        XmlSerializer xmlSerializer;

        Root root = new Root();
        root.SensorList = new List<Sensor>();
        root.SensorList.Add(new SensorA() {A = "foo"});
        root.SensorList.Add(new SensorB() {B = "bar"});

        // Tell the serializer about derived types
        xmlSerializer = new XmlSerializer(typeof (Root), 
            new Type[]{typeof (SensorA), typeof(SensorB)});
        StringBuilder stringBuilder = new StringBuilder();
        using (StringWriter stringWriter = new StringWriter(stringBuilder))
        {
            xmlSerializer.Serialize(stringWriter, root);
        }

        // Output the serialized XML
        Console.WriteLine(stringBuilder.ToString());

        Root root2;
        using (StringReader stringReader = new StringReader(stringBuilder.ToString()))
        {
            root2 = (Root) xmlSerializer.Deserialize(stringReader);
        }
    }
}

The output from the Console.WriteLine statement is:

<?xml version="1.0" encoding="utf-16"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Sensor>
    <Sensor xsi:type="SensorA">
      <A>foo</A>
    </Sensor>
    <Sensor xsi:type="SensorB">
      <B>bar</B>
    </Sensor>
  </Sensor>
</Root>

Upvotes: 1

Related Questions