Я пытаюсь десериализовать пользовательский класс с помощью XmlSerializer и имею несколько проблем, в том, что я не знаю типа, который я собираюсь десериализовать (он подключается), и я «Трудно определить его.C# Custom Xml Serialization
Я нашел this post, который выглядит аналогичным, но не может заставить его работать с моим подходом, потому что мне нужно десериализовать интерфейс, который является XmlSerializable.
У меня в настоящее время есть та часть формы. Обратите внимание, что я ожидаю и должен иметь возможность обрабатывать как класс A, так и класс B, которые будут реализованы через плагин. Поэтому, если я могу избежать использования IXmlSerializable (что, я думаю, не могу), это было бы здорово.
ReadXml for A - это то, за что я застрял. Однако, если есть другие изменения, которые я могу внести для улучшения системы, я буду рад сделать это.
public class A : IXmlSerializable
{
public IB MyB { get; set;}
public void ReadXml(System.Xml.XmlReader reader)
{
// deserialize other member attributes
SeekElement(reader, "MyB");
string typeName = reader.GetAttribute("Type");
// Somehow need to the type based on the typename. From potentially
//an external assembly. Is it possible to use the extra types passed
//into an XMlSerializer Constructor???
Type bType = ???
// Somehow then need to deserialize B's Members
// Deserialize X
// Deserialize Y
}
public void WriteXml(System.Xml.XmlWriter writer)
{
// serialize other members as attributes
writer.WriteStartElement("MyB");
writer.WriteAttributeString("Type", this.MyB.GetType().ToString());
this.MyB.WriteXml(writer);
writer.WriteEndElement();
}
private void SeekElement(XmlReader reader, string elementName)
{
ReaderToNextNode(reader);
while (reader.Name != elementName)
{
ReaderToNextNode(reader);
}
}
private void ReaderToNextNode(XmlReader reader)
{
reader.Read();
while (reader.NodeType == XmlNodeType.Whitespace)
{
reader.Read();
}
}
}
public interface IB : IXmlSerializable
{
}
public class B : IB
{
public void ReadXml(XmlReader reader)
{
this.X = Convert.ToDouble(reader.GetAttribute("x"));
this.Y = Convert.ToDouble(reader.GetAttribute("y"));
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("x", this.X.ToString());
writer.WriteAttributeString("y", this.Y.ToString());
}
}
ПРИМЕЧАНИЕ: Обновлено, поскольку я понял, что B должен был использовать интерфейс IB. Извините за неверный вопрос.
Это интересный подход. Итак, вы предлагаете в этот момент вызвать ReadXml() на созданном типе для инициализации членов? Это может работать в зависимости от того, могу ли я получить тип + создать один из возможно внешнего типа в моей библиотеке. – Ian
Я отвечал на ваш комментарий, где вы сказали: «Как-то нужно, чтобы тип был основан на имени типа». –
Спасибо, Джон. Прочитав тип из XML, создав экземпляр, я смог де-сериализовать его с помощью метода ReadXml созданного экземпляра. Работает с удовольствием и отлично работает с моим интерфейсом. – Ian