我有一个实现公共接口的对象列表。如果我尝试简单地序列化它,我得到一个很好的异常,告诉我序列化程序不能序列化接口:
private readonly ObservableCollection<ICanHasInterface> children = new ObservableCollection<ICanHasInterface>();
public ObservableCollection<ICanHasInterface> Children
{
get { return children; }
}
=&GT; “无法序列化类型的成员......因为它是一个界面”
显然要求序列化程序获取对象的类型并使用属性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
块,我对此为何无能为力;任何想法?
答案 0 :(得分:1)
在反序列化时,序列化程序使用属性getter获取集合实例,然后为每个项调用Add()。它不会调用您的属性设置器。像这样:
YourClass c = new YourClass();
c.ChildrenSerialized.Add(ReadValue());
...
为了保持集合同步,您需要自定义从属性getter返回的集合的Add()行为。
更好的选择是将ChildrenSerialized属性更改为使用对象[]。对于数组,序列化程序将值读入数组,然后使用值调用属性setter。