For application configuration, I frequently will create a configuration class with configuration values for the application that I then deserialize into an object to utilize. The configuration object is usually databound to a user interface control so that the configuration can be changed and persisted by the user. The configuration class typically has default values assigned to the properties so that there is always a default configuration. This has worked well. I recently had a situation where I had a list of strings that provided some default path information. And what I saw made me realize I did not completely know how the object properties are being populated during XML deserialization to an object.
So I created a simple example to show the behavior. The following is a simple class that has a couple of properties that have some code defaults.
[Serializable]
public class TestConfiguration
{
public String Name
{
get
{
return mName;
}
set
{
mName = value;
}
}private String mName = "Pete Sebeck";
public List<String> Associates
{
get
{
return mAssociates;
}
set
{
mAssociates = value;
}
} private List<String> mAssociates = new List<string>() { "Jon", "Natalie" };
public override String ToString()
{
StringBuilder buffer = new StringBuilder();
buffer.AppendLine(String.Format("Name: {0}", Name));
buffer.AppendLine("Associates:");
foreach(String associate in mAssociates)
{
buffer.AppendLine(String.Format("\t{0}", associate));
}
return buffer.ToString();
}
}
And here is a main that creates a new objects, prints the state of the object to the console, serializes (xml) it to a file, the reconstitutes an object from that file and again prints the state of the object to the console. What I expected was an object that matched what was serialized. What I got was the default object with contents of the serialized list added to the default.
static void Main(string[] args)
{
// Create a default object
TestConfiguration configuration = new TestConfiguration();
Console.WriteLine(configuration.ToString());
// Serialize the object
XmlSerializer writer = new XmlSerializer(typeof(TestConfiguration));
StreamWriter filewriter = new StreamWriter("TestConfiguration.xml");
writer.Serialize(filewriter, configuration);
filewriter.Close();
// Now deserialize the xml into another object
XmlSerializer reader = new XmlSerializer(typeof(TestConfiguration));
StreamReader filereader = new StreamReader("TestConfiguration.xml");
TestConfiguration deserializedconfiguration = (TestConfiguration)reader.Deserialize(filereader);
filereader.Close();
Console.WriteLine(deserializedconfiguration.ToString());
Console.ReadLine();
}
Results:
Name: Pete Sebeck
Associates:
Jon
Natalie
Name: Pete Sebeck
Associates:
Jon
Natalie
Jon
Natalie
I guess I always thought the List property would be set rather than appended to. Does anyone have a pointer to the deserialization process for collections? I apparently do now know the correct search terms as my attempts are coming up empty. I see other posts describing what I am seeing and their approach of implementing serialization themselves. I am more looking for a pointer that describes what happens when a collection is deserialized so I can explain to myself what I am seeing.