Take this example object:
public class XmlTest
{
private List<int> integerList = new List<int> { 1, 2, 3 };
public List<int> IntegerList
{
get { return integerList; }
set { integerList = value; }
}
}
We have a single property which is a list of integer values. If we create an object and serialize it:
XmlTest xmlTest = new XmlTest();
TextWriter writer = new StreamWriter("test.xml");
XmlSerializer serializer = new XmlSerializer(typeof(XmlTest));
serializer.Serialize(writer, xmlTest);
writer.Close();
we get the following Xml, just like we would expect:
<?xml version="1.0" encoding="utf-8"?>
<XmlTest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<IntegerList>
<int>1</int>
<int>2</int>
<int>3</int>
</IntegerList>
</XmlTest>
But when we deserialize the generated Xml like so:
FileStream fs = new FileStream("test.xml", FileMode.Open);
XmlReader reader = new XmlTextReader(fs);
xmlTest = (XmlTest)serializer.Deserialize(reader);
fs.Close();
we get a surprise. The integer list in the deserialized object has 6 items rather than three. The list ends up being "1, 2, 3, 1, 2, 3". Why is this? It has to do with the details of how lists are deserialized. If you put a breakpoint in the "set" of the IntegerList property, you will find that it never gets called during deserialization. Instead, it seems that the .NET deserializer uses "get" to access the property, and then calls "Add()" to deserialize the list items. Because we initialize the list to "1, 2, 3", those items are already there before adding the items from the Xml.
I don't know that I am prepared to call this behavior "wrong", but it certainly was unexpected for me. Ideally, serializing and then deserializing an object would result in the exact same data. In this case, not so much.
A better behavior, I think, would be for the deserialzer to creat a new list, populate it from the Xml, and then call my property's "set" method to hook it into my object. This also would allow you to put business logic in your property and have it survive serialization. At the very least, it would probably make sense to clear the list before adding items during deserialization.