Производная десериализация класса
У меня проблема с десериализацией в моей программе логического моделирования.
Вот мои классы элементов:
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; }
}
А вот классы, отвечающие за сокеты:
public class InputData : SocketData
{
}
public class SocketData
{
public Guid Id { get; set; }
public SignalData SignalData { get; set; }
}
SignalData здесь не важен. Поэтому я не буду писать это (чтобы сохранить этот вопрос в чистоте), если кто-то не скажет, что это необходимо.
CircuitData очень важна:
[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);
}
}
Провода сейчас не важны.
Теперь я написал сериализацию:
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.");
}
}
Он работает так, как я хотел, он производит этот документ 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>
Но у меня проблема с моей десериализацией. Вот код:
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;
}
Теперь он десериализует мой Circuit.xml
к объекту, но этот объект содержит только Id
а также Delay
не содержит Input1
, Input2
или же Output
, Таким образом, это рассматривается как Element
, не как AndGate
, Я пытался решить это в течение дня, но кажется, что ни у кого нет такой проблемы.
1 ответ
У меня есть предложение для вас, сделайте Write
универсальный метод, как это и создать сериализатор с помощью objectToSerialize.GetType()
:
public static void Write<T>(T objectToSerialize, string fileName)
{
var xmlSerializer = new XmlSerializer(objectToSerialize.GetType());
...
}
XmlSerializer.Deserialize()
метод возвращает объект, вы можете сделать свой Read
универсальный метод, подобный этому:
public static T Read<T>(string fileName)
{
var serializer = new XmlSerializer(typeof(T));
using (StreamReader file = new StreamReader(fileName))
{
return (T)serializer.Deserialize(file);
}
}
Помимо этого вы можете прочитать о:
- XmlInclude, который используется при сериализации производных классов.
- XmlArray и XmlArrayItem, которые используются для управления сериализацией массивов