mic*_*ael 11 c# inheritance serialization xml-serialization
我有这样的结构:
public interface A
{
public void method();
}
public class B : A
{
}
public class C : A
{
}
List<A> list;
Run Code Online (Sandbox Code Playgroud)
List包含B和C类型的对象,它们还有一些我想保留的字段,我现在可以序列化它,反序列化并获取正确的对象实例吗?最好是XML
编辑:
是否有任何简单的方法来序列化包含接口的列表,然后将其反序列化回B和C实例?
假设您正在使用内置的.net XML序列化,您应该看看以下属性:
System.Xml.Serialization.XmlIncludeAttribute
Run Code Online (Sandbox Code Playgroud)
它允许您在序列化/反序列化时指示序列化程序包含其他类型.
向列表中添加新类型而不更新序列化元数据是错误的常见原因,请确保您有足够的测试覆盖率.
我会使用抽象类而不是接口(因为不能序列化一种类型的接口),然后使用XmlInclude属性而不是硬编码类型,我会在串行和反序列化方法中将已知类型添加到XmlSerializer中,如此:
string listXml = Serialize<List<A>>(ListA, new Type[] { typeof(B), typeof(C) });
List<IA> NewList = Deserialize<List<A>>(listXml, new Type[] { typeof(B), typeof(C) });
private static T Deserialize<T>(string Xml, Type[] KnownTypes)
{
XmlSerializer xs = new XmlSerializer(typeof(T),KnownTypes);
StringReader sr = new StringReader(Xml);
return (T)xs.Deserialize(sr);
}
private static string Serialize<T>(Object obj, Type[] KnownTypes)
{
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
XmlSerializer xs = new XmlSerializer(typeof(T), KnownTypes);
xs.Serialize(sw, obj);
}
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
您可以尝试使用DataContractSerializer:
public interface A
{
}
public class B : A
{
}
public class C : A
{
}
class Program
{
static void Main(string[] args)
{
List<A> list = new List<A>(new A[] { new B(), new C() });
var serializer = new DataContractSerializer(
list.GetType(), new[] { typeof(B), typeof(C) });
var sb = new StringBuilder();
using (var stringWriter = new StringWriter(sb))
using (var writer = XmlWriter.Create(stringWriter))
{
serializer.WriteObject(writer, list);
}
using (var stringReader = new StringReader(sb.ToString()))
using (var reader = XmlReader.Create(stringReader))
{
list = (List<A>)serializer.ReadObject(reader);
}
}
}
Run Code Online (Sandbox Code Playgroud)