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:
- Why chooses the Deserializer the Array type as concrete implementation of the IList interface?
- Is it possible to change the settings which class should be taken for each interface?
- If i have a self defined interface and several implementations of this interface, is it possible to tell the Deserializer which concrete class should be taken for a given interface?