Click here to Skip to main content
15,891,248 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello.
I have a problem with deserialization with my logic simulation program.
Here are my element classes:
C#
public class AndGateData : TwoInputGateData
    {
        
    }
public class TwoInputGateData : GateData
    {
        public TwoInputGateData()
        {
            Input2 = new InputData();
            Input1 = new InputData();
        }
        public InputData Input1 { get; set; }
        public InputData Input2 { get; set; }
    }
public class GateData : ElementData
    {
        public GateData()
        {
            OutputData = new OutputData();
        }

        public OutputData OutputData { get; set; }
    }
public class ElementData
    {
        public int Delay { get; set; }
        public Guid Id { get; set; }
    }



And here are classes responsible for sockets:
C#
public class InputData : SocketData
    {
        
    }
public class SocketData
    {
        public Guid Id { get; set; }
        public SignalData SignalData { get; set; }
    }


SignalData is not important here, so I won't write it(in order to keep this question clean) here unlesss somebody says it is necesarry.
Very important is CircuitData:
C#
[XmlRoot("Circuit")]
    public class CircuitData
    {
        [XmlElement(typeof(AndGateData))]
        [XmlElement(typeof(OrGateData))]
        public List<ElementData> elements = new List<ElementData>();
        public List<WireData> wires = new List<WireData>();
        public void AddElement(ElementData element)
        {
            elements.Add(element);
        }
        public void AddWire(WireData wire)
        {
            wires.Add(wire);
        }
    }

Wires are not important right now.
Now I have written some Serialization:
C#
public class CircuitDataWriter
    {
         public static void Write(object obj, string fileName)
         {
             var xmlFormat = new XmlSerializer(typeof(CircuitData));
             using(Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None) )
             {
                 xmlFormat.Serialize(fStream,obj);
             }
             Console.WriteLine("Circuit saved in XML format.");
         }
        
    }

It works just like I wanted, it produces that xml document:
XML
<?xml version="1.0"?>
-<Circuit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
-<AndGateData> 
  <Delay>10</Delay> 
  <Id>bfee6dd7-5946-4b7b-9d0b-15d5cf60e2bf</Id> 
  -<OutputData> <Id>00000000-0000-0000-0000-000000000000</Id> </OutputData> 
  -<Input1> <Id>7c767caf-79a9-4c94-9e39-5c38ec946d1a</Id> <SignalData xsi:type="SignalDataOn"/> </Input1> 
  -<Input2> <Id>d2cad8f8-8528-4db3-9534-9baadb6a2a14</Id> <SignalData xsi:type="SignalDataOff"/> </Input2> 
</AndGateData> 
<wires/> 
</Circuit>


But I have problem with my DESERIALIZATION. Here is the code:
C#
public static CircuitData Read()
        {
            var reader = new XmlSerializer(typeof(CircuitData));
            StreamReader file = new StreamReader("Circuit.xml");
            var returnCircuitData = new CircuitData();
            returnCircuitData = (CircuitData) reader.Deserialize(file);
            return returnCircuitData;
        }


Now, it deserializes my Circuit.xml to object, but this object only contains Id and Delay, it does not contain Input1, Input2 or Output. So it is treaten like Element, not like AndGate. I try to solve it out for a day but it seems that no one has that kind of problem.

Thank you for your Answers.

Regards,
MS
Posted

I've just tried this and I can't see a problem with the deserialisation. Do you cast the individual items of CircuitData's elements list to their actual run-time type?

C#
CircuitData cd = Read(); // deserialise
foreach (ElementData ed in cd.elements) {
  if (ed is TwoInputGateData) {
    TwoInputGateData gate = (TwoInputGateData)ed;
    Console.WriteLine(gate.GetType());
    Console.WriteLine(gate.Input1);
    Console.WriteLine(gate.Input2);
    Console.WriteLine(gate.OutputData);
  } else {
      // etc
  }
}
 
Share this answer
 
Comments
Michael Szczepaniak 2-Nov-12 13:50pm    
Alan you are right, not casting elements form list to their actual types was the problem.
The XmlSerializer does not support polymorphism like you expect. Try using my fastJSON[^] project instead.
 
Share this answer
 
Comments
Michael Szczepaniak 2-Nov-12 17:21pm    
Mehdi are you sure? It works now... Or maybe there is something I don't know?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900