[Serializable] and ISerializable
Eagle-eyed readers will have noticed that in all the preceding
examples the classes are sealed
. This is no
accident. Marking a class as [Serializable]
and
deciding whether to implement ISerializable
has
some specific implications for both base and derived types, and
deserves separate discussion.
Consider the following serializable class hierarchy:
[Serializable] public class Person { public string Name; public int Age; // Rest of class... } [Serializable] public sealed class Student: Person { public string Course; // Rest of class... }
In this example both Person
and
Student
are serializable, and both classes use the
default runtime serialization behavior since neither class implements
ISerializable
.
Now imagine that the developer of Person
decides
for some reason to implement ISerializable
and
provide a deserialization constructor to control
Person
serialization. The new version of
Person
might look like this:
[Serializable] public class Person : ISerialization { public string Name; public int Age; public void GetObjectData(SerializationInfo si, StreamingContext sc) { si.AddValue("IChangedTheNameFieldName", Name); si.AddValue("IChangedTheAgeFieldName", Age); } protected Person(SerializationInfo si, StreamingContext sc) { Name = si.GetString("IChangedTheNameFieldName"); Age = sc.GetInt32("IChangedTheAgeFieldName"); } // Rest of class... }
Although this works for instances of Perso
n, this
change breaks serialization of Student
instances. Serializing a ...
Get C# in a Nutshell, Second Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.