序列化编译时类型未知的对象
Serializing Object whose type is not known at compile time
我得到了一个模型列表,这些模型可能会有所不同,并且在编译时无法知道它们的类型。我必须实现此集合的唯一选择是制作 List<Object>
或 List<dynamic>
(我知道第一个更快更好)。问题是当试图序列化这个集合时,.Net 的 XmlSerializer
抛出一个异常说明 "Data whose type is not known at compile time cannot be serialized"。问题是,根据这个例外,是否有可能做到这一点,如果可以,如何才能有效地做到这一点。
更新:
这里不能选择二进制序列化(不能使用)
(注意:下面较早的评论指的是与问题的较早版本不同的解决方案。)
你试过吗?
var types = theList.Select(o => o.GetType()).Distinct().ToArray();
var serializer = new XmlSerializer(typeof(List<object>), types);
...
当然,反序列化会更难;您需要从 XML 中解析出必要的类型,然后使用反射将类型对象放入数组中,这样您就可以实例化 XmlSerializer。您可以通过将 XML 与列出必要类型的一些元数据打包在一起来稍微简化一下。
逐项序列化列表项,例如:
public class ModelA
{
public int Foo { get; set; }
}
public class ModelB
{
public string Bar { get; set; }
}
class Program
{
static void Main(string[] args)
{
var stream = new MemoryStream();
var writer = XmlWriter.Create(stream);
var list = new List<object>()
{
new ModelA() { Foo = 9 },
new ModelB() { Bar = "some string" }
};
writer.WriteStartElement("root");
list.ForEach(x => ToXml(x, writer));
writer.WriteEndElement();
writer.Flush();
stream.Seek(0, SeekOrigin.Begin);
var doc = new XmlDocument();
doc.Load(XmlReader.Create(stream));
Console.WriteLine(doc.OuterXml);
Console.ReadLine();
}
private static void ToXml(object obj, XmlWriter writer)
{
var serializer = new XmlSerializer(obj.GetType());
serializer.Serialize(writer, obj);
}
}
我得到了一个模型列表,这些模型可能会有所不同,并且在编译时无法知道它们的类型。我必须实现此集合的唯一选择是制作 List<Object>
或 List<dynamic>
(我知道第一个更快更好)。问题是当试图序列化这个集合时,.Net 的 XmlSerializer
抛出一个异常说明 "Data whose type is not known at compile time cannot be serialized"。问题是,根据这个例外,是否有可能做到这一点,如果可以,如何才能有效地做到这一点。
更新:
这里不能选择二进制序列化(不能使用)
(注意:下面较早的评论指的是与问题的较早版本不同的解决方案。)
你试过吗?
var types = theList.Select(o => o.GetType()).Distinct().ToArray();
var serializer = new XmlSerializer(typeof(List<object>), types);
...
当然,反序列化会更难;您需要从 XML 中解析出必要的类型,然后使用反射将类型对象放入数组中,这样您就可以实例化 XmlSerializer。您可以通过将 XML 与列出必要类型的一些元数据打包在一起来稍微简化一下。
逐项序列化列表项,例如:
public class ModelA
{
public int Foo { get; set; }
}
public class ModelB
{
public string Bar { get; set; }
}
class Program
{
static void Main(string[] args)
{
var stream = new MemoryStream();
var writer = XmlWriter.Create(stream);
var list = new List<object>()
{
new ModelA() { Foo = 9 },
new ModelB() { Bar = "some string" }
};
writer.WriteStartElement("root");
list.ForEach(x => ToXml(x, writer));
writer.WriteEndElement();
writer.Flush();
stream.Seek(0, SeekOrigin.Begin);
var doc = new XmlDocument();
doc.Load(XmlReader.Create(stream));
Console.WriteLine(doc.OuterXml);
Console.ReadLine();
}
private static void ToXml(object obj, XmlWriter writer)
{
var serializer = new XmlSerializer(obj.GetType());
serializer.Serialize(writer, obj);
}
}