Today at work I spent a fair amount of time tracking down a bug. I had made some minor changes to several C# classes for FxCop and standards compliance (changing ID to Id, etc.), and the unit tests were failing.
I finally found the problem. Some of the objects were serialized to XML for persistence (in production code, not just test code). When the tests deserialized previously stored objects, some of the property names differed in case (ID vs. Id, for instance). When no case-sensitive match was found, the serialization code silently ignored those properties and initialized them to default values (0 or null). The new objects had most of their properties set, but a few were not.
The book C# Cookbook (O’Reilly) warns about this; versioning is a major issue when objects are serialized to persistent storage. “Never change the class” isn’t always realistic.
Serialization may seem like an easy solution, but there’s no free lunch.
Fortunately, the unit tests caught this (and caught other non-obvious issues in the last few days). Rule #1: some unit tests are better than no unit tests.
Update - Nov. 16, 2007
One solution may be to add a Version or SchemaVersion property, comment the class with dire warnings about renaming properties, and insure that default field initializers are provided for any new properties.
Update - Jan. 9, 2008
The book Effective C# contains a discussion of binary serialization and offers a solution for versioning. It’s a fair amount of work, though.
No Comments/Pingbacks for this post yet...
Development Central is the blog of Bill Sorensen, a professional software developer. Much of this will relate to C#, .NET, and OOP in general.
Disclaimer
These postings are provided "AS IS" with no warranties and confer no rights.