Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XmlSerializer and Collection property with private setter

Say I have a simple class like so

[Serializeable]
public class MyClass
{
    public MyClass()
    {
       this.MyCollection = new List<int>();
    }


    public List<int> MyCollection { get; private set;}
}

If I try to deserialize this using XmlSerializer I get an error saying that MyCollection is readonly and cannot be assigned to. However I don't want to make the setter public as this can cause all kinds of problems if the user of the class assigns to it. FxCop rightly warns against this: Collection properties should be read only

However on the bottom of the page in the community added content is this:

XmlSerializer understands read-only collections Collection properties do not have to be read-write for the XmlSerializer to serialize and deserialize the contents correctly. The XmlSerializer will look for a method called Add on collection properties that implement ICollection or IEnumerable, and use that to populate the collection when deserializing an instance of the owner type.

However it just doesn't seem to be the case (as I get the InvalidOperationException). What am I able to do that obeys the best practice of keeping the property setter private while still allowing me to use the XmlSerializer?

like image 475
Ray Avatar asked May 21 '09 05:05

Ray


People also ask

Can I make XmlSerializer ignore the namespace on Deserialization?

Yes, you can tell the XmlSerializer to ignore namespaces during de-serialization.

Is XmlSerializer thread safe?

Since XmlSerializer is one of the few thread safe classes in the framework you really only need a single instance of each serializer even in a multithreaded application. The only thing left for you to do, is to devise a way to always retrieve the same instance.

Why do we use XmlSerializer class?

XmlSerializer enables you to control how objects are encoded into XML. The XmlSerializer enables you to control how objects are encoded into XML, it has a number of constructors.

How does the XmlSerializer work C#?

The XmlSerializer creates C# (. cs) files and compiles them into . dll files in the directory named by the TEMP environment variable; serialization occurs with those DLLs. These serialization assemblies can be generated in advance and signed by using the SGen.exe tool.


1 Answers

Your private setter is causing the issue. The XmlSerializer class will work fine with the class I have given below. The XmlSerializer class was invented before private setters were introduced, so it is probably not checking that correctly when it scans the class type using reflection. Maybe you should report this to Microsoft as a bug.

public class MyClass
{
    private List<int> _myCollection;

    public MyClass()
    {
        _myCollection = new List<int>();
    }

    public List<int> MyCollection
    {
        get
        {
            return this._myCollection;
        }
    }
}
like image 64
Martin Brown Avatar answered Sep 21 '22 19:09

Martin Brown