Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you have issues with serialization, you can always separate the application-code from the serialization code. That is, place conversion classes that convert to/from your serialized state. The serialized instances can have exposed any empty constructors and properties needed and their only job is to serialize state. Meanwhile, your application logic works with the non-serializable, immutable objects. This way you do not mix your serialization concerns with logical concerns which brings with it a host of disadvantages as you are finding out.</p> <p>EDIT: Here's some example code:</p> <pre><code>public class Animal { public string Name { get; private set; } public double Weight { get; private set; } public Habitat Habitat { get; private set; } internal Animal(string name, double weight, Habitat habitat) { this.Name = name; this.Weight = weight; this.Habitat = habitat; } public void Swim(); } public class SerializableAnimal { public string Name { get; set; } public double Weight { get; set; } public SerializableHabitat Habitat { get; set; } //assuming the "Habitat" class is also immutable } public static class AnimalSerializer { public static SerializableAnimal CreateSerializable(Animal animal) { return new SerializableAnimal {Name=animal.Name, Weight=animal.Weight, Habitat=HabitatSerializer.CreateSerializable(animal.Habitat)}; } public static Animal CreateFromSerialized(SerializableAnimal serialized) { return new Animal(serialized.Name, serialized.Weight, HabitatSerializer.CreateFromSerialized(serialized.Habitat)); } //or if you're using your "Static fields" design, you can switch/case on the name public static Animal CreateFromSerialized(SerializableAnimal serialized) { switch (serialized.Name) { case "Otter" : return Animal.Otter } return null; //or throw exception } } </code></pre> <p>Then your application logic for serialization might look something like:</p> <pre><code>Animal myAnimal = new Animal("Otter", 10, "North America"); Animal myOtherAnimal = Animal.Duck; //static fields example SerializableAnimal serializable = AnimalSerializer.CreateSerializable(myAnimal); string xml = XmlSerialize(serializable); SerializableAnimal deserialized = XmlDeserializer&lt;SerializableAnimal&gt;(xml); Animal myAnimal = AnimalSerializer.CreateFromSerialized(deserialized); </code></pre> <p>Just to reiterate, the SerializableAnimal class and usage is <em>ONLY</em> used in the final layer(s) of your application that need to serialize/deserialize. <em>Everything</em> else works against your immutable Animal classes.</p> <p>EDITx2: Another major benefit of this managed separation is you can deal with legacy changes in your code. For example, you have a <code>Fish</code> type, which is pretty broad. Maybe you split it into <code>Shark</code> and <code>Goldfish</code> later and decide all your old <code>Fish</code> type should be considered <code>Goldfish</code>. With this separation of serialization, you can now place a check for any old Fish and convert them to Goldfish whereas direct serialization would result in an exception because Fish no longer exists.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload