C# Xml Serializer deserializes list to count of 0 instead of null

Viewed 1835

I am confused on how XmlSerializer works behind the scenes. I have a class that deserializes XML into an object. What I am seeing is for the following two elements that are NOT part of the Xml being deserialized.

[XmlRootAttribute("MyClass", Namespace = "", IsNullable = false)]
public class MyClass
{
    private string comments;
    public string Comments
    {
        set { comments = value; }
        get { return comments; }
    }

    private System.Collections.Generic.List<string> tests = null;
    public System.Collections.Generic.List<string> Tests
    {
        get { return tests; }
        set { tests = value; }
    }
}

Let's take the following XML as an example:

<MyClass>
  <SomeNode>value</SomeNode>
</MyClass>

You notice that Tests and Comments are NOT part of the XML.

When this XML gets deserialized Comments is null(which is expected) and Tests is an empty list with a count of 0.

If someone could explain this to me it would be much appreciated. What I would prefer is that if <Tests> is missing from the XML then the list should remain null, but if a (possibly empty) node <Tests /> is present then the list should get allocated.

4 Answers

When you apply [System.Xml.Serialization.XmlElement(IsNullable = true)] to the property, the List will be null after deserialization.

Another possibility is to use the "magic" "Specified" suffix:

public bool TestsSpecified {get;set;}

If you have a serialized field/property XXX and a boolean property XXXSpecified, then the bool property is set according to whether or not the main field/property was set.

We wound up here after a google search for the same issue. What we ended up doing was checking for Count == 0, after deserialization, and manually setting the property to null;

...
var varMyDeserializedClass = MyXmlSerializer.Deserialize(new StringReader(myInput));
if (varMyDeserializedClass.ListProperty.Count == 0)
{
  varMyDeserializedClass.ListProperty = null;
}
...

It's a cheap workaround, but provides the expected result and is useful to avoid refactoring or redesign.

Related