【问题标题】:Deserialize a class with interface反序列化具有接口的类
【发布时间】:2013-01-01 06:51:47
【问题描述】:

我有一个包含接口成员变量的类。我该如何反序列化这个类

interface ISensor { }

[Serializable]
class Sensor: ISensor { }

[Serializable]
class Root
{
    [XmlElement("Sensor")]
    public List<ISensor> SensorList{ get; set; }
}

我的 XML 会是这样的

  <?xml version="1.0" encoding="us-ascii"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Sensor >
        <SensorName>Name1</SensorName>
        <SensorValue>0.0</SensorValue>
    </Sensor>
    <Sensor>
        <SensorName>Name2</SensorName>
        <SensorValue>148.00</SensorValue>
    </Sensor>
</Root>

【问题讨论】:

标签: c# serialization


【解决方案1】:

假设您使用的是XmlSerializer,则序列化和反序列化都需要进行两项更改:

  1. 告诉序列化程序可以出现的类型列表,也就是继承自Sensor 的类型。
  2. 为 List 使用类而不是接口,换句话说,将 List&lt;ISensor&gt; 替换为 List&lt;Sensor&gt;

不幸的是,XmlSerializer 不能以您想要的方式处理接口。有关更多信息,请参阅XmlSerializer serialize generic List of interface

如果不能使用基类,您可以通过实现IXmlSerializable 来编写自己的 XML 序列化程序。覆盖 ReadXml 并手动解析 XML。

例如:

public interface ISensor { }

[Serializable]
public class Sensor : ISensor { }

[Serializable]
public class Root
{
    // Changed List<ISensor> to List<Sensor>. I also changed
    // XmlElement to XmlArray so it would appear around the list.       
    [XmlArray("Sensor")]
    public List<Sensor> SensorList { get; set; }
}

[Serializable]
public class SensorA : Sensor
{
    [XmlElement("A")]
    public string A { get; set; }
}

[Serializable]
public class SensorB : Sensor
{
    [XmlElement("B")]
    public string B { get; set; }
}

class Program
{
    public static void Main(string[] args)
    {
        XmlSerializer xmlSerializer;

        Root root = new Root();
        root.SensorList = new List<Sensor>();
        root.SensorList.Add(new SensorA() {A = "foo"});
        root.SensorList.Add(new SensorB() {B = "bar"});

        // Tell the serializer about derived types
        xmlSerializer = new XmlSerializer(typeof (Root), 
            new Type[]{typeof (SensorA), typeof(SensorB)});
        StringBuilder stringBuilder = new StringBuilder();
        using (StringWriter stringWriter = new StringWriter(stringBuilder))
        {
            xmlSerializer.Serialize(stringWriter, root);
        }

        // Output the serialized XML
        Console.WriteLine(stringBuilder.ToString());

        Root root2;
        using (StringReader stringReader = new StringReader(stringBuilder.ToString()))
        {
            root2 = (Root) xmlSerializer.Deserialize(stringReader);
        }
    }
}

Console.WriteLine 语句的输出是:

<?xml version="1.0" encoding="utf-16"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Sensor>
    <Sensor xsi:type="SensorA">
      <A>foo</A>
    </Sensor>
    <Sensor xsi:type="SensorB">
      <B>bar</B>
    </Sensor>
  </Sensor>
</Root>

【讨论】:

  • 如何进行反序列化
  • 我已经更新了关于反序列化的答案和示例,尽管所需的更改是相同的。你有什么特别需要的吗?
  • 就我而言,我将无法更改 XML 的格式(检查问题中的 XML)。我需要反序列化该 XMl。
  • 有没有办法指定将 加载到 SensorA 类中。在 java 中有一个选项可以指定它。 [serializerObj.alias("Sensor", SensorA.class);]C#中有没有类似的东西
  • 你能用Sensor元素的内容格式更新问题吗?没有它,将很难准确确定如何反序列化 XML。
猜你喜欢
  • 2014-07-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多