DataContractSerializer.ReadObject avoids the constructor?

  • Thread starter Thread starter not_a_commie
  • Start date Start date
N

not_a_commie

DataContractSerializer.ReadObject creates an object without calling
any constructors. It doesn't require a parameterless constructor like
all other deserialization implementations I've ever seen or heard
about. That's just weird. How do they do it?

What's more weird, though, is that they don't initialize any fields.
That leads to strange bugs. Of course that's why they have the
OnDeserialized attribute -- you need to initialize your fields in that
method in addition to elsewhere in the class.
 
not_a_commie said:
DataContractSerializer.ReadObject creates an object without calling
any constructors. It doesn't require a parameterless constructor like
all other deserialization implementations I've ever seen or heard
about. That's just weird. How do they do it?

Reflection.

And, by the way, .NET serialization (not XmlSerializer, but the more
low-level one - BinaryFormatter and SoapFormatter) also does the same thing.
What's more weird, though, is that they don't initialize any fields.
That leads to strange bugs. Of course that's why they have the
OnDeserialized attribute -- you need to initialize your fields in that
method in addition to elsewhere in the class.

The idea is that your object should be serialized transparently - i.e., it
is only created once, so the constructor is only called once. That it is
later "frozen" when serialized, and "unfrozen" when deserialized, shouldn't
matter - it's still the very same object. This is enforced by the fact that,
by default, all fields, including private ones, are serialized, and you have
to apply [NotSerializable] where needed yourself. Thus, if your object graph
does not include third-party non-serializable objects, and you don't use
[NotSerializable], you shouldn't be able to detect whether your graph is
newly constructed, or deserialized - hence no constructor call.

Of course, in practice, things are usually more complicated. But, as you've
pointed out yourself, that's what [OnDeserialized] is for.
 
This is enforced by the fact that,
by default, all fields, including private ones, are serialized,
and you have
to apply [NotSerializable] where needed yourself.

That is true for BinaryFormatter/SoapFormatter, but unless I am
mistaken DataContractSerializer (etc) only serializes members marked
as [DataMember]; it is "opt in", where-as BinaryFormatter /
XmlSerializer etc are "opt out".

Marc
 
This is enforced by the fact that,
by default, all fields, including private ones, are serialized,
and you have
to apply [NotSerializable] where needed yourself.

That is true for BinaryFormatter/SoapFormatter, but unless I am
mistaken DataContractSerializer (etc) only serializes members marked
as [DataMember]; it is "opt in", where-as BinaryFormatter /
XmlSerializer etc are "opt out".

Marc
 
Marc Gravell said:
This is enforced by the fact that,
by default, all fields, including private ones, are serialized,
and you have
to apply [NotSerializable] where needed yourself.

That is true for BinaryFormatter/SoapFormatter, but unless I am
mistaken DataContractSerializer (etc) only serializes members marked
as [DataMember]; it is "opt in", where-as BinaryFormatter /
XmlSerializer etc are "opt out".

It was the case in 3.0, but changed in 3.5. Since 3.5, if you don't mark
your class with [DataContract], it tries to infer the contract by itself
rather than signalling an error.
 
Reflection.

What does reflection have to do with creating an object without
calling any constructors on that object? I'm not aware of any
reflection API to do this.
 
Back
Top