Сериализация списка содержит интерфейс для XML - PullRequest
2 голосов
/ 15 июля 2009

Я читал, но не нашел решения своей проблемы

В настоящее время я работаю с бизнес-объектом, который будет содержать все мои данные, и нам нужно преобразовать этот объект в XML и из него.

Мой объект содержит список действий (список ...), но есть 2 типа действий (на данный момент). Мне нужно типы действий SimpleAction и CompositeAction, и они оба наследуются от IAction, позволяя им обоим храниться в списке действий.

Теперь вы, вероятно, видите проблему, поскольку интерфейсы не могут быть сериализованы, так как они не содержат данных.

Как, возможно, с помощью некоторого примера кода, написать класс или сериализатор, который получает этот тип объекта и выполняет затем сериализацию объекта с правильным типом?

Код:

  [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
}

Любая помощь будет принята с благодарностью. :)

Ответы [ 3 ]

4 голосов
/ 15 июля 2009

Вы можете использовать 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; }
2 голосов
/ 16 июля 2009

Хорошо, я создал решение, которое, как мне кажется, делает то, что я хочу, очень хорошо.

То, что я сделал, это вместо того, чтобы держать

 [XmlArray("Actions")]
 public List<IAction> Actions { get; set; }

Я решил создать класс ActionsCollection, который обрабатывал бы List, НО также позволил мне использовать 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
}
0 голосов
/ 15 июля 2009

Может быть, если вы производите два ваших класса действий из общего абстрактного базового класса, который реализует интерфейс?

public interface IAction {}
public abstract class ActionBase : IAction {}
public class SimpleAction : ActionBase {}
public class ComplexAction : ActionBase {}

Тогда вместо использования List<IAction> используйте List<ActionBase>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...