У меня есть класс, который мне нужно для сериализации/десериализации, и я на полпути - у меня есть функционал сериализации, ниже XML. Однако, так как я уверен, реализации IXmlSerializable
себя, я не зная, что реализация ReadXml
должна выглядеть, учитывая, что SomeGenericClass<T>
был сериализовать с использованием атрибутов на основе маркировки, а не явной реализации, если IXmlSerializable
Как реализовать ReadXml для SomeClass: IList <IFoo>, где все экземпляры IFoo являются IFoo <T> переменных T
<?xml version="1.0" encoding="utf-16"?>
<FooContainer FooName="DoSomething">
<SomeGenericClassOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Value="Foobar" Name="firstParam" Description="First Paramater Serialized" />
<SomeGenericClassOfInt32 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Value="10000" Name="nextParam" Description="Second Serialized parameter" />
</FooContainer>
Что я хочу сериализовать обратно в экземпляр:
public class FooContainer : IList<ISomeGenericClassBase>, IXmlSerializable
{
public string FooName {get;set;}
void IXmlSerializable.WriteXml(XmlWriter writer) {
var serializer = XmlSerializer.FromTypes(new Type[]{SomeGenericBaseClass})[0];
this
.Select(item=>SomeGenericClassBase.ConvertToMe(item))
.ToList()
.ForEach(item=>serializer.Serialize(writer, item));
}
// IList Implementation omitted - wraps a private List<ISomeGenericClassBase>
}
Если список будет содержать экземпляры вдоль этих линий:
public interface ISomeGenericClassBase
{
}
public interface ISomeGenericBaseClass<T> : ISomeGenericBaseClass
{
}
public class SomeGenericClassBase : ISomeGenericClassBase
{
public static SomeGenericClassBase ConvertToMe(ISomeGenericClassBase target) {
return new SomeGenericClassBase() {Property1 = target.Property1; Property2 = target.Property2}
}
public static ISomeGenericBaseClass ExpantToTyped(SomeGenericClassBase target) {
// Implementation omitted - converts a base class instance to a generic instance by working out the generic type from saved data and reconstructing
}
}
public class SomeGenericClass<T> : SomeGenericClassBase, ISomeGenericBaseClass<T>
{
[XmlAttribute]
public string Name {get;set;}
[XmlAttribute]
public string Description{get;set;}
[XmlAttribute]
public T Value {get;set;}
[XmlElement("")]
public T[] ValidOptions {get;set;}
}
EDIT: Expanded реализации - понял, как это было, это не иллюстрировать проблему правильно
Основной проблемой является то, что я хочу, чтобы иметь возможность сериализовать элементы, которые только реализуют интерфейс, даже если я только вернусь SomeGenericClassBase
экземпляров. На основе подхода, используемого в методе ExpandToTyped
, я ожидаю, что потребители этого класса будут сохранять достаточные данные в их реализациями, которые позволят результирующим классам быть преобразованными обратно в исходную форму по мере необходимости. Так что да, есть потеря верности, но я могу жить в обмен на гибкость использования списка интерфейсов вместо списка базовых классов.
Зачем использовать атрибуты xml для сериализации, но не для десериализации? –
Извините за это - просто перечитайте то, что я спросил, и я понимаю, почему у вас возник вопрос. Я расширил этот вопрос, чтобы быть более наглядным примером того, что я пытаюсь сделать. Сводная причина состоит в том, что список состоит из интерфейсов, а не базовых классов. – tobriand
Спасибо за комментарий, хотя - на самом деле указал мне в правильном направлении! Решение заключалось в том, чтобы сменить IXmlSerializable и использовать сериализуемый класс преобразователей - будет вводить его немного. – tobriand