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.
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.
What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
What you are observing is that members referring to modifiable collections such as List<T>
are automatically pre-allocated by XmlSerializer
at the beginning of deserialization. I am not aware of any place where this behavior is documented. It may be related to the behavior described in this answer to XML Deserialization of collection property with code defaults, which explains that, since XmlSerializer
supports adding to get-only and pre-allocated collections, if a pre-allocated collection contains default items then the deserialized items will be appended to it - possibly duplicating the contents. Microsoft may simply have chosen to pre-allocate all modifiable collections at the beginning of deserialization as the simplest way of implementing this.
The workaround from that answer, namely to use a surrogate array property, works here as well. Since an array cannot be appended to, XmlSerializer
must accumulate all the values and set them back when deserialization is finished. But if the relevant tag is never encountered, XmlSerializer
apparently does not begin accumulating values and so does not call the array setter. This seems to prevent the default pre-allocation of collections that you don't want:
[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;
[XmlIgnore]
public System.Collections.Generic.List<string> Tests
{
get { return tests; }
set { tests = value; }
}
[XmlArray("Tests")]
public string[] TestsArray
{
get
{
return (Tests == null ? null : Tests.ToArray());
}
set
{
if (value == null)
return;
(Tests = Tests ?? new List<string>(value.Length)).AddRange(value);
}
}
}
Sample .Net fiddle showing that Tests
is allocated only when appropriate.
When you apply [System.Xml.Serialization.XmlElement(IsNullable = true)]
to the property, the List will be null after deserialization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With