Enrico
Enrico

Reputation: 621

WPF C# Deserialize an observable collection <string> with XmlSerializer adds extra items

I wish to save and load a class (MeasConSettings) that contains a ObservableCollection<string> The problem is the list is initialized in my constructor so when I do the following:

XmlSerializer serializer = new XmlSerializer(typeof(MeasConSettings));

A list is created with items 1 2 3 4. It saves all fine, but on the loading side it goes wrong:

MeasConSettings loadedSettings = (MeasConSettings)serializer.Deserialize(stream);

It starts from the initialized list and adds the loaded list items instead of overwriting them so the result is a list with items 1 2 3 4 1 2 3 4.

Obviously the solution would be to remove the initialization from the constructor as shown in this topic:Deserializing List with XmlSerializer Causing Extra Items but then what if the file does not contain the list (e.g. a previous version of a saved file), If I remove the initialization and there is no list present in the saved file, there will be no items in the list. This is not acceptable so:

Is there a proper way to load an observable collection with initialization in the constructor without ending up with duplicate items?

or

Is there a proper way to check if a saved file contains certain parameters?

Upvotes: 0

Views: 927

Answers (1)

Kevin Gosse
Kevin Gosse

Reputation: 39007

If I remove the initialization and there is no list present in the saved file, there will be no items in the list. This is not acceptable

Then just handle this special case in the initialization.

public void Init()
{
    if (this.List == null)
    {
        // Initialize the list
    }
}

From there, you just have to call the Init method everytime you create a MeasConSettings object (either by calling the constructor or by using the deserializer).

That said, I'm not overly fond of the initialization methods, as they lack visibility and a fellow developer can forget to call them. As an alternative, you can use a getter:

private List<int> list;

public List<int> List
{
    get
    {
        if (this.list == null)
        {
            this.list = new List<int> { 1, 2, 3, 4 };
        }

        return this.list;
    }

    set
    {
        this.list = value;
    }
}

Note: This code isn't thread-safe.

Upvotes: 1

Related Questions