I have several classes that are immutable once their initial values are set. Eric Lippert calls this write-once immutability.
Implementing write-once immutability in
"Realio-trulio" immutability involves the constructor. Popsicle immutability is where you can do, for example:
Person p = new Person();
p.Name = "Fred";
p.DateOfBirth = DateTime.Today;
p.Freeze(); // **now** immutable (edit attempts throw an exception)
(or the same with an object initializer)
This fits DataContractSerializer quite well, as long as you handle to on-serialized callback to do the Freeze. XmlSerializer doesn't do serialization callbacks, so is more work.
Either would suit if you use custom serialization (IXmlSerializable), though. Likewise, custom serialization is broadly doable with realio-trulio immutability, but is painful - and it is a bit of a lie, as it is "create once, then call interface method" - so not really properly immutable.
For true immutability, use a DTO.