序列化接口数组



我正在尝试实现一种方法将一组对象保存到文件,然后再次将其读回对象。 我想将对象序列化为 XML(或 JSON(。这些对象由一个主对象组成,该主对象包含所有其他对象的数组。该数组的类型为 Interface,以允许具有一些常见功能的几种不同类型的子对象。 显然,在反序列化过程中会出现问题,因为接口对象的类型未知。

例:

[Serializable]
public class MasterClass
{
public ImyInterface[] subObjects;
}
public interface ImyInterface
{
}

如何序列化/反序列化这些对象?

我的建议: 在序列化数据中添加有关对象类型的信息。 使用与接口不同的解决方案。

这不是序列化数据的唯一方法,但它是框架中现成的解决方案:

DataContractSerializer支持这一点,您不介意为接口的每个可用实现添加属性:

[DataContract]
[KnownType(typeof(MyImpl))] // You'd have to do this for every implementation of ImyInterface
public class MasterClass
{
[DataMember]
public ImyInterface[] subObjects;
}
public interface ImyInterface
{
}
public class MyImpl : ImyInterface
{
...
}

序列化/反序列化:

MasterClass mc = ...
using (var stream = new MemoryStream())
{
DataContractSerializer ser = new DataContractSerializer(typeof(MasterClass));
ser.WriteObject(stream, mc);
stream.Position = 0;
var deserialized = ser.ReadObject(stream);
}

对于 JSON,您可以改用DataContractJsonSerializer

一种解决方案是使用抽象类而不是接口:

public class MasterClass
{
public MyAbstractClass[] subObjects;
}
[XmlInclude(typeof(MyImpl ))] //Include all classes that inherits from the abstract class
public abstract class MyAbstractClass
{
}
public class MyImpl : MyAbstractClass
{
...
}

它可以使用 XmlSerializer 进行序列化/反序列化:

MasterClass mc = ...
using (FileStream fs = File.Create("objects.xml"))
{
xs = new XmlSerializer(typeof(MasterClass));
xs.Serialize(fs, mc);
}

using (StreamReader file = new StreamReader("objects.xml"))
{
XmlSerializer reader = new XmlSerializer(typeof(MasterClass));
var deserialized = reader.Deserialize(file);
}