0

I have a Config object which I am serializing into XML so I can load it back again later on. In my configuration object I have a dictionary objects

    public Dictionary<int, FooConfiguration> Foos
    {
        get { return foos; }
        set
        {
            if (foos != value)
            {
                foos = value;
                OnPropertyChanged(() => foos);
            }
        }
    }

When I am serializing it doesn't seem to like serializing dictionaries which I can understand, they are complicated objects. So as a workaround I figured I would decorate the property with [XMLIgnore] and create a list of my objects which would get the values from the dictionary.

    public List<FooConfiguration> FooConfigurations
    {
        get { return Foos.Values.ToList(); }
        set
        {
            int fooNumber = 0;

            foreach (var fooConfiguration in value)
            {
                foos.Add(fooNumber++, fooConfiguration);
            }
        }
    }

This worked as far as serializing goes. I could now see these objects in my XML. The problem is, it was never hitting the setter. Why Would a list be able to serialize but not deserialize?

I have eventually fixed this by using a FooConfiguration[] instead of a list but this seems a bit weird if you ask me.

As you can see I have a solution, I am just really wanting to understand why its doing what it's doing better.

Keithin8a
  • 961
  • 7
  • 32
  • Possible duplicate of [How to XML-serialize a dictionary](http://stackoverflow.com/questions/3671259/how-to-xml-serialize-a-dictionary) – Jakub Jankowski Sep 19 '16 at 08:56
  • @JakubJankowski Thanks for that, That is quite an obvious way of serializing a dictionary and pretty similar to my solution. While my main question is about the list not deserializing I do not think it is a duplicate. Maybe i should change the title? – Keithin8a Sep 19 '16 at 09:03
  • Use an array `FooConfiguration []` rather than a `List` for your surrogate property. For an explanation why, see [Cannot deserialize XML into a list using XML Deserializer](https://stackoverflow.com/questions/26179792/cannot-deserialize-xml-into-a-list-using-xml-deserializer/26624551#26624551) – dbc Sep 21 '16 at 04:12
  • @dbc Thanks, yeah thats what I ended up doing to get around it. My question was about why the list didn't work. – Keithin8a Sep 23 '16 at 11:05

1 Answers1

2

If your list has a non-null value, it won't need to hit the setter; it just calls Add on the list it is given. And in your case, the list you are handing it is detached from the actual data (becuase you created it in the getter).

So basically, it is deserializing the data into an object that is left on the floor.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Thanks, I can't believe I never thought about this, it's quite obvious when you think about it. – Keithin8a Sep 19 '16 at 09:08
  • @Keithin8a the intent, obviously, is to avoid allocating extra lists; but to be fair, this side effect is quite nuanced – Marc Gravell Sep 19 '16 at 09:12
  • @Keithin8a possible fix: `get { return (Foos == null || Foos.Count == 0) ? null : Foos.Values.ToList(); }` – Marc Gravell Sep 19 '16 at 09:12
  • Sorry I may be dumb here, but I don't think I understand how that helps the deserialization. Does this force it to use the setter if Foos is null or empty? – Keithin8a Sep 19 '16 at 09:23
  • @Keithin8a it it *gets* a `null` instance, it will `new` one up, deserialize, and call `set`... unless, of course, it decides to do it the other way around: `new` one up, call `set`, and then deserialize - in which case you're no better off :( – Marc Gravell Sep 19 '16 at 10:48
  • Use an array rather than a list for a surrogate property. The list will be set back immediately after being allocated, while the array will only get set back after being populated. See [Cannot deserialize XML into a list using XML Deserializer](https://stackoverflow.com/questions/26179792/cannot-deserialize-xml-into-a-list-using-xml-deserializer/26624551#26624551). – dbc Sep 21 '16 at 04:09
  • 1
    @Keithin8a see dbc's hint above – Marc Gravell Sep 21 '16 at 11:48
  • @MarcGravell thanks for notifying me of this. I really appreciate users going the extra mile. I have actually used an array (see end of question) but I just wanted to know my list property wasn't working which you answered perfectly. – Keithin8a Sep 23 '16 at 11:06