Я читал, но я не нашел решения моей проблемы
В настоящее время я работаю с бизнес-объектом, который будет хранить все мои данные, и нам нужно преобразовать этот объект в XML и из него.
Мой объект содержит список Actions (List...), но есть 2 типа действия (пока). У меня есть действия типа SimpleAction и CompositeAction, и они оба наследуют от IAction, позволяя им быть оба в списке Actions.
Теперь вы можете увидеть проблему, поскольку интерфейсы не могут быть сериализованы, поскольку они не содержат данных.
Как, с некоторым примером кода, я пишу класс или сериализатор, который получает этот тип объекта и выполняет сериализацию объекта с правильным типом?
Некоторые коды:
[XmlArray("Actions")]
public List<IAction> Actions { get; set; }
public interface IAction
{
int ID { get; set; }
ParameterCollection Parameters { get; set; }
List<SectionEntity> Validation { get; set; }
TestResultEntity Result { get; set; }
string Exception { get; set; }
}
[XmlType("A")]
public class SimpleActionEntity : IAction
{
#region IAction Members
[XmlAttribute("ID")]
public int ID { get; set; }
[XmlIgnore]
public ParameterCollection Parameters { get; set; }
[XmlIgnore]
public List<SectionEntity> Validation { get; set; }
[XmlIgnore]
public TestResultEntity Result { get; set; }
[XmlElement("Exception")]
public string Exception { get; set; }
#endregion
}
Любая помощь будет принята с благодарностью.:)
Хорошо, я создал решение, которое, как я чувствую, делает то, что мне очень нравится.
То, что я сделал, а не проведение
[XmlArray("Actions")]
public List<IAction> Actions { get; set; }
Я решил создать класс ActionsCollection, который обрабатывал List BUT, также позволял мне использовать IXMLSerializable для переопределения методов ReadXml и WriteXML, чтобы я мог обрабатывать способ сериализации и десериализации списка.
[XmlElement("Actions")]
public ActionCollection Actions { get; set; }
public class ActionCollection: CollectionBase, IXmlSerializable
{
#region IList Members
...
#endregion
#region ICollection Members
...
#endregion
#region IEnumerable Members
...
#endregion
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
//TODO
}
public void WriteXml(System.Xml.XmlWriter writer)
{
foreach (IAction oAction in List)
{
XmlSerializer s = new XmlSerializer(oAction.GetType());
s.Serialize(writer, oAction);
}
}
#endregion
}
Вы можете использовать XmlArrayItemAttribute, поскольку мы не обсуждали его, чтобы создать список IAction, поэтому полезно создавать базовый класс
public interface IAction {}
public abstract class ActionBase : IAction {}
public class SimpleAction : ActionBase {}
public class ComplexAction : ActionBase {}
[XmlArray("Actions")]
[XmlArrayItem(typeof(SimpleAction)),XmlArrayItem(typeof(ComplexAction))]
public List<ActionBase> Actions { get; set; }
Фактически вы также можете управлять именами элементов в XML файле следующим образом:
[XmlArray("Actions")]
[XmlArrayItem(typeof(SimpleAction),ElementName = "A")]
[XmlArrayItem(typeof(ComplexAction),ElementName = "B")]
public List<ActionBase> Actions { get; set; }
Может быть, если вы получите два класса действий из общего абстрактного базового класса, который реализует интерфейс?
public interface IAction {}
public abstract class ActionBase : IAction {}
public class SimpleAction : ActionBase {}
public class ComplexAction : ActionBase {}
Затем вместо List<IAction>
используйте List<ActionBase>
.
SimpleAction
наследует от другого базового класса? и не может наследовать от другого базового класса.