使用XML序列化序列化接口列表

Pau*_*aul 1 c# interface xml-serialization

我有下面的类,我需要使用XML序列化器进行序列化

我知道XML序列化器不喜欢接口

但是,我们的编码标准通常涉及始终对接口而非特定类进行编码

我想到了一种无需更改会导致许多编译问题以及违反我们标准的类型就可以流式传输此列表的方法

我的想法是拥有一个属性,该属性可以读取“计量表”列表并将其转换为具体的类,然后在进行序列化时完全忽略计量表

但是,XML仍需要使用Meters作为元素名称

但是这不起作用

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.Xml.Serialization;

    public class MeterWalkOrder
    {
        public MeterWalkOrder()
        {
            Meters = new List<IMeter>();
        }

        public String Name { get; set; }


        [XmlIgnore]
        public List<IMeter> Meters { get; set; }

        [XmlArrayItem(ElementName = "Meter")]
        [XmlElement(ElementName = "Meters")]
        public List<Meter> SerializableMeters
        {
            get
            {
                return Meters.Cast<Meter>().ToList();
            }
            set
            {
                Meters = new List<IMeter>(value);                
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法解决?

我的XML(无法更改)如下

   <MeterWalkOrder>
      <Name>Red Route</Name>
      <Meters>
        <Meter>
          <MeterID>1</MeterID>
          <SerialNumber>12345</SerialNumber>
        </Meter>
        <Meter>
          <MeterID>2</MeterID>
          <SerialNumber>SE</SerialNumber>
        </Meter>
      </Meters>
    </MeterWalkOrder>
Run Code Online (Sandbox Code Playgroud)

顶级错误是

出现错误,反映了类型'WindowsFormsApplication1.Classes.MeterWalkOrder'。

内部的例外是

{“ XmlElement,XmlText和XmlAnyElement不能与XmlAttribute,XmlAnyAttribute,XmlArray或XmlArrayItem结合使用。”}

我真的很想避免为使用具体类列表设置先例

sa_*_*213 5

您将需要替换[XmlElement(ElementName = "Meters")][XmlArray(ElementName = "Meters")]作为错误状态:

{"XmlElement, XmlText, and XmlAnyElement cannot be used in conjunction with XmlAttribute, XmlAnyAttribute, XmlArray, or XmlArrayItem."}
Run Code Online (Sandbox Code Playgroud)

要为定义一个数组,XmlSerializer您可以将其标记为,XmlArray并将其对应的项目标记为XmlArrayItem

例:

public class MeterWalkOrder
{
    public MeterWalkOrder()
    {
        Meters = new List<IMeter>();
    }

    public String Name { get; set; }

    [XmlIgnore]
    public List<IMeter> Meters { get; set; }

    [XmlArrayItem(ElementName = "Meter")]
    [XmlArray(ElementName = "Meters")]
    public List<Meter> SerializableMeters
    {
        get
        {
            return Meters.Cast<Meter>().ToList();
        }
        set
        {
            Meters = new List<IMeter>(value);                
        }
    }
}

 public interface IMeter {
   int MeterID { get; set; }
 }

 public class Meter : IMeter {
     public int MeterID { get; set; }
     public string SerialNumber { get; set; }
 }
Run Code Online (Sandbox Code Playgroud)

测试:

var data = new MeterWalkOrder{ Name = "Red Route", Meters = new List<IMeter>
{
     new Meter{ MeterID = 1, SerialNumber = "12345"},
     new Meter{ MeterID = 2, SerialNumber = "SE"}
}};
using (var stream = new FileStream("C:\\Users\\Adam\\Desktop\\Test2.xml", FileMode.OpenOrCreate))
{
    XmlSerializer ser = new XmlSerializer(typeof(MeterWalkOrder));
    ser.Serialize(stream, data);
}
Run Code Online (Sandbox Code Playgroud)

结果:

<?xml version="1.0"?>
<MeterWalkOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Red Route</Name>
  <Meters>
    <Meter>
      <MeterID>1</MeterID>
      <SerialNumber>12345</SerialNumber>
    </Meter>
    <Meter>
      <MeterID>2</MeterID>
      <SerialNumber>SE</SerialNumber>
    </Meter>
  </Meters>
</MeterWalkOrder>
Run Code Online (Sandbox Code Playgroud)