1

Just wondering if anyone knows how the XmlSerializer determines the order for deserializing any given object's properties.

Added info:

I have a class like this:

    private bool _hasGaps = false;
    public bool HasGaps
    {
        get { return _hasGaps; }
        set
        {
            _hasGaps = value;
        }
    }

    private List<GapInfo> _gaps;
    public List<GapInfo> Gaps
    {
        get { return _gaps; }
        set
        {
            _gaps = value;
        }
    }

I set a breakpoint in both Gaps setter and HasGaps setter, Gaps gets deserialized first.

More info

Here's what the XML looks like:

<Tube Id="3df08765-c4e7-4a87-a0ed-ec76169b47af" Name="Tube">
  <HasGaps>false</HasGaps>
  <Gaps />
</Tube>
Carlo
  • 25,602
  • 32
  • 128
  • 176
  • What's your XML look like? Think about this a moment. How would deserialization work if it were not possible to determine what the XML must look like? No other order is possible. – John Saunders Feb 04 '10 at 19:52
  • I'd guess it was the order they appear in the serialized xml used as input. – sylvanaar Feb 04 '10 at 19:52
  • @sylvanaar: you'd be wrong. It doesn't permit XML elements to be in arbitrary orders. – John Saunders Feb 04 '10 at 19:53
  • You say you set a breakpoint in the setters. Does HasGaps ever get called? – John Saunders Feb 04 '10 at 19:57
  • It never got called. However, that Gaps get accessor did. – Carlo Feb 04 '10 at 19:58
  • Carlo, if it never got called, then you don't know the order. – John Saunders Feb 04 '10 at 20:10
  • The mapping is by element name, so why is order even relevant? The object is created using the parameterless constructor, and then its properties are set. – sylvanaar Feb 04 '10 at 20:48
  • @sylvanaar: There's something we're trying to do to prevent the serializer from setting a null Gaps property to an empty Gaps list. We need the property to be null. If it's serialized with a null value, it also should be deserialized with a null value, and this does not happen. My question revolts around this requirement. More info here: http://stackoverflow.com/questions/2188619/is-there-a-way-to-avoid-the-xmlserializer-to-not-initialize-a-null-property-when – Carlo Feb 04 '10 at 20:54

1 Answers1

2

It deserializes them in the order they appear in the class.

Did you have reason to believe it might use a different order?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • Thanks for the suggestion, but that doesn't seem to be the case, see added info in my question. – Carlo Feb 04 '10 at 19:49
  • BTW, what's your source for saying that it deserializes them in the order they appear? Maybe there's something there that could give me a clue. – Carlo Feb 04 '10 at 20:08
  • @Carlo: common sense. The XML appears in a given order. The properties appear in a given order. Nothing (no annotation) specifies the order. What order could possibly be used? Only one - the order of the properties must be the order of the elements. – John Saunders Feb 04 '10 at 20:11
  • So based on your last comment in my question, I assume you're now saying there is no way to know the order? – Carlo Feb 04 '10 at 20:13
  • The order is the order of the properties. – John Saunders Feb 04 '10 at 20:15
  • I disagree. The Gaps property is the last defined property in my class, and somehow it's the first one to get deserialized. I set a break point in the Gaps set accessor, and in there I check all the other properties and they're not set. Then I set another breakpoint on any other property and it gets set. I know it's the same object thanks to the GetHashCode() method. Thanks for the help anyway. – Carlo Feb 04 '10 at 20:27
  • If you never see the other property setter called, then `Gaps` isn't the _last_ property to be set, it's the _only_ property to be set. If you saw `Gaps` set, then `HasGaps`, then you'd be able to say that `Gaps` is first. – John Saunders Feb 04 '10 at 21:39
  • Yeah, that's just what happened. Gaps is set first, then HasGaps is set, then TimeCreated, Name, TimeModified, etc. But for some reeason, Gaps is always set first. How do I know this? With the breakpoint in the Gaps set accesor, I check in the Watch window for Name, which is = null, TimeCreated is DateTime.Min, TimeModified too. Then when I set a breakpoint on the Name set accessor, the value changes of course, and Gaps is already initialized as an empty list. – Carlo Feb 04 '10 at 22:42
  • No, no, no. Try an example with `Gaps` being an integer or something. You're seeing the difference between treatment of a list and treatment of a primitive type. – John Saunders Feb 04 '10 at 22:46
  • I'll do that in a moment. What is this difference I'm seeing? – Carlo Feb 04 '10 at 22:51
  • Ok, with primitive types it does deserialize in order, does this means that it doesn't deserialize the list first because it's not a primitive type? If so, it doesn't really deserialize in the order they appear in the class. – Carlo Feb 05 '10 at 01:11