XmlSerializer错误序列化接口对象
问题描述:
我有一个实现通用接口的对象列表。如果我尝试简单的序列化它,我得到一个不错的异常告诉我,该串行不能序列接口:XmlSerializer错误序列化接口对象
private readonly ObservableCollection<ICanHasInterface> children = new ObservableCollection<ICanHasInterface>();
public ObservableCollection<ICanHasInterface> Children
{
get { return children; }
}
=>“无法序列成员...类型的...因为它是一个接口”
显然要求序列化程序获取对象的类型并用属性xsi:type
(如果对象从另一个类继承)标记XmlElement太多。
,因为我不想要实现IXmlSerializable
,我想出了一个解决办法,其看起来最初有为:
private readonly ObservableCollection<ICanHasInterface> children = new ObservableCollection<ICanHasInterface>();
[XmlIgnore()]
public ObservableCollection<ICanHasInterface> Children
{
get { return children; }
}
[XmlElement("Child")]
public List<object> ChildrenSerialized
{
get
{
return new List<object>(Children);
}
set
{
Children.Clear();
foreach (var child in value)
{
if (child is ICanHasInterface) AddChild(child as ICanHasInterface);
}
}
}
有了这个至少系列化工作得很好(注:请指定XmlInclude
属性的类型,可以在原始列表中或在串行器的构造函数中交出类型数组),但是如果对象被反序列化,则Children
集合会变空,因为set
块在反序列化期间永远不会到达,所以我对于为什么会这样是;有任何想法吗?
答
关于反序列化,序列化程序使用属性获取器获取集合实例,然后为每个项目调用Add()。它不会调用你的属性设置器。例如:
YourClass c = new YourClass();
c.ChildrenSerialized.Add(ReadValue());
...
为了保持同步的集合,您需要自定义您从属性获取器返回的集合的Add()行为。
更好的选择是将ChildrenSerialized属性更改为使用对象[]。对于数组,序列化程序将该值读入数组,然后使用该值调用属性设置器。
非常感谢,与阵列完美配合! – 2011-01-10 21:06:06