Version Tolerant Serialization is a very nice addition to the serialization framework. At long last, one can actually use serialization in order to save data, without worrying about breaking changes in serializable types, which cause deserialization between versions to simply not work.
After reading the above article, I turned back to read about the OptionalField attribute, which offers the ability to mark a field as new, so that when deserialization of older versions of the type happens, the field will be ignored. However, when a new serialization process (or a deserialization of a stream containing a current instance of the type) happens, it will get treated as part of the data.
What bothered me about the attribute is what the VersionAdded parameter it uses takes. It takes an integer. At first it seemed weird that the designer chose to only treat the major version of the assembly (assembly version is made up of Major, Minor, Build, and Revision), but after re-reading a few lines told me, I realized that this wasn’t the case – each type now has its own version numbers!
I have to say that I personally think this is a design mistake – why would you need to save additional data about the versioning of the type, when the data about the version already exists in the serialized data? Plus, now all these new version number have to be maintained: how will I find where version 2 of my type which is now at version 8 is in my source control?
What I think is that the version parameter should have been either of the following:
- System.Single (float) – This way, the version specified would be Major.Minor, which is, according to Microsoft’s guidelines, the only part of the version which indicates (or may indicate, breaking changes):
Changing the build number implies that the revision is a mandatory bug fix upgrade and should be installed. These so-called Quick Fix Engineering (QFE) bug fixes should be compatible with previous versions. Likewise, changing the revision number implies that only minor changes have been made, but the new version is still fully backward-compatible. Changing the minor version number implies substantial changes have been made but that backward-compatibility has been maintained whenever possible. Minor versions might include features not available in their predecessors, but older features should remain unaffected by the revision. Changing the major version number implies that the new version is substantially different from the previous version and is most likely not backward-compatible.
– Change Management During Deployment, Microsoft Corporation
- System.Version (through the use of System.String) – This would mean that Microsoft accepts the fact that some people like to handle their versions a little differently than what they would like to see, allowing to specify all parts of the assembly’s version.
With either of the above, the deserialization engine would be able to alert (using an exception) if the version and the optionality of the field mismatch (e.g. version is 1.4 and the value does not exist, but the field was marked as added in version 1.3).
Another use for this would be the automatic documentation tools that could use the metadata exposed by the attribute to document the version in which the field was added (if documented).