0

I am using XmlSerializer to serialize a List of objects of a class that also have some List objects.

public class Configuration
{
    private IList<Project> _projects = null;
    public IList<Project> Projects
    {
        get
        {
            return new List<Project>(_projects);
        }

        set
        {
            _projects = value;

        }
    }

    public void Load()
    {
        //Here takes place the deserialization
    }

    public void Save()
    {
        //Here takes place the serialization
    }
}

public class Project
{
    public string Name { get; set; }

    private IList<Document> _documents = null;
    public IList<Document> Documents
    {
        get
        {
            return new List<Document>(_documents);
        }

        set
        {
            _documents = value;

        }
    }

    private IList<Test> _tests = null;
    public IList<Test> Tests
    {
        get
        {
            return new List<Test>(_tests);
        }

        set
        {
            _tests = value;

        }
    }
}

This implementation does not work throwing an exception at runtime about Documents or Tests variable being of an interface type (IList, a detail that seems not to be a problem with Projects). If I change Documents and Tests to List, then the exception is gone, but another problem arises (not related). Serialization does not serialize the Documents and Tests arrays (and thus deserialization cannot restore those variables). If I change the custom get implementation for both properties, returning _documents and _tests directly, it all works as expected. But again, Projects property also has a custom get implementation and it works as expected.

public class Configuration
{
    private IList<Project> _projects = null;
    public IList<Project> Projects
    {
        get
        {
            return new List<Project>(_projects);
        }

        set
        {
            _projects = value;

        }
    }

    public void Load()
    {
        //Here takes place the deserialization
    }

    public void Save()
    {
        //Here takes place the serialization
    }
}

public class Project
{
    public string Name { get; set; }

    public List<Document> Documents { get; set; }
    public List<Test> Tests { get; set; }
}

Of course I can live with this but I suspect that I may be doing something wrong. First I see no reason why I can serialize Projects being a IList and not Documents nor Tests. Secondly I see no reason why the custom gettter for Projects works, but it is preventing de correct serialization of Documents and Tests.

I also tried to use DataContractSerializer and it works out of the box but I prefer the clearer xml output from XmlSerializer.

Any hints?

P.S.: A full VS 2015 solution with the complete implementation and tests can be downloaded in the following link: https://www.dropbox.com/s/38cp12rgi2o4pqw/SerializationTest.zip?dl=0

Super Rey
  • 375
  • 2
  • 11
  • 2
    You want to make your DTOs as simple as possible. I would maybe even use `Document[]` and `Test[]`. The problem is that the serializer doesn't know which implementation of `lList` to use behind the scenes when deserializing. – dana Mar 08 '17 at 16:19
  • @dana I can understand that, but why IList Projects is not an issue in the serialization? – Super Rey Mar 08 '17 at 16:22
  • I agree with @dana. Another one question: why do your getters return `new List(_projects);`? They will return new list every time create with a copy constructor (not sure how copy constructor behaves when null is passed, probably just return an empty list), but `_project` variable will definitely not be set at any time. It will always be `null`. It is unlikely that it is an expected behavior? – Yeldar Kurmangaliyev Mar 08 '17 at 16:25
  • @YeldarKurmangaliyev as I said I understand the exception thrown by C#, IList is an interface type and cannot be serialized. But it is being serialized (at least in the Projects property). About the getters implementation, that can be a matter for another discussion :), but it is the way I choosed to avoid unintentional modification to the list, i.e. what objects are on the list. – Super Rey Mar 08 '17 at 16:37
  • *Serialization works, but deserialization does not restore the Documents and Tests arrays*. That is explained in [XML Deserialization of collection property with code defaults](http://stackoverflow.com/q/27927496/3744182). – dbc Mar 08 '17 at 18:46
  • @dbc I just realized that is wrong, after changing IList to List, serialization for Documents and Tests properties does not work. It only work when I remove the custom getter. I edited the description accordingly. – Super Rey Mar 09 '17 at 10:54

0 Answers0