Just imagine you have the following class
[DataContract]
public class NamedList
{
[DataMember]
public string Name { get; set; }
[DataMember]
public IList<string> Items { get; private set; }
public DumpList(string name)
{
Name = name;
Items = new List<string>();
}
}
If you serialize this into a file, it is quite easy, cause the concrete class behind the IList
is known and can be serialized.
But what happens if you try to deserialize this file back into memory?
It works without any direct error occuring.
The problem comes if you try to add or remove something from the list. In that case you'll get an exception. And the root of this exception comes from the case that the deserialized object uses as concrete implementation for the IList an Array.
To avoid this problem in this simple example is easy. Just serialize the concrete backing store instead of the public property and make the change in the constructor:
[DataMember(Name = "Items")]
private List<string> _Items;
public IList<string> Items
{
get
{
return _Items;
}
}
public DumpList(string name)
{
Name = name;
_Items = new List<string>();
}
But the more interesting question is:
If you use the NetDataContractSerializer
, which stores type information along with the serialized object, your problem should be solved. However, it does at the same time reduce interoperability to non-.NET clients.