Menu

Serialization Pitfalls

October 29, 2014 - Programming

It is a rather basic concept. The idea of saving some state within your program to disk, and restoring it later. Particularly when you are dealing with an object graph in memory and want to restore it. Unfortunately, the easiest way isn’t always the best way.

BinaryFormatter

Interestingly, .NET actually contains built-in serialization capabilities. The basic premise is that your class implement ISerializable and also implement a constructor and a specific constructor, as seen here:

This method does work, really- it’s not super hard to use and setup though it can be a bit of a pain in the butt to maintain. Of interest is that you can GetValue() and AddValue() arbitrary objects, as long as they are also ISerializable. You can use particular Formatters to take your Serialization Information and save it. BinaryFormatter is in particular the one I found most reliable.

There are however some rather significant issues. The first is that you really don’t have a lot of options when it goes to actually serializing data. There is BinaryFormatter and a few JSON converters which don’t work particularly well. The main issue is not so much the underlying interfaces and requirements, but really it’s two-fold; there are few reliable IFormatter implementations that you can rely on from launch to launch (BinaryFormatter fails very easily, and the errors are rather generic) and additionally when dealing with deep object heirarchies small mistakes such as forgetting to mark a method as virtual or forgetting to implement a constructor can cause hard-to-trace bugs in the program.

I speak mostly from my experience writing the logic in BASeBlock to save and load Levelsets. It has been some time, but the serialization nightmares still pester me. Additionally, it bothers me that the Binary format that the files end up as are not very transparent; I cannot easily look inside them without deserializing them in the game editor and if it fails- well, delete it and try again. This rather dampens my attempts to create a “standard” levelset that shows off it’s capabilities.

Recently I set to the task of switching to a new Serialization scheme. I quickly gave up when I realized how much work it would be and just how much code I had written and how many classes needed changed and so on. For that moment I rather gave up. Ideally, however, I would be able to save to XML, ideally with the XDocument/XElement logic. Then save load from XML in much the same way as now. Originally I thought “simple, I’ll just make something like what I already have but create methods that serialize to a XElement and constructors that accept and read from an XElement. This framework would work, but the thing that bothered me is that it was duplication; I had two completely separate but similar save methods strewn about. I gave up on it at the time.

I did attempt previously to create a way to serialize and deserialize from XML via the Formatter method, but this has some rather troubling issues. The main one is that you cannot access the property bag of the object (the SerializationInfo); otherwise it would be relatively straightforward; just take the propertybag of t =he main object and save it and it’s descendants to nodes and attributes and values and such. But this does not appear to be the case. Instead, you serialize in place to a stream, serializing each object directly to the stream. It might be possible nonetheless but it will certainly require that I rethink my approach. At any rate for the “long-term” goal, BASeBlock would be greatly serviced by simply having it use XML files rather than binary files, if only for compatibility.

In looking over BASeBlock while writing this, I’ve come to find a lot of older code that I thought was quite robust which, in the process of my work I have copy-pasted into classes for our products which have subsequently morphed in form, function, and in generall been extended vastly in capability. Some of these I even discussed previously on this blog, such as my DebugLogger. I’m uncertain of how “safe” it would be to copy them BACK to BASeBlock, so I’ve not done so; I’d rather keep my personal projects and work projects as far away from each other to prevent “code ownership” issues. If I copy code from my personal projects to my work projects than from that point on I like to consider them “forked”. But this has the additional issue- If I improve the work version, would writing the same improvements to my personal version still cause it to count as belonging to my employer? It’s a tricky question which I’ve pretty much avoided altogether by taking the rather unsavoury approach of avoiding my personal projects (though to be fair the real reason I’ve not gotten back to them is simply due to time constraints). At any rate it is interesting to think that at any one point a programmer/developer might have code or programs they are proud of, but a few years down the line they look back on that program in disgust. BASeBlock doesn’t quite fit that criteria, but parts of it do. Components and classes that I used to consider excellent, robust, and awesome have ended up getting improved and now that old version feels like getting into a go-kart after driving a Pagani. I like to think this is a good thing. At the same time, I do wonder if perhaps I should try to create personal projects in another programming language just to “top up” on that language. Continuous self-improvement is particularly important I feel but I’ve also not exactly followed my own advice on that front for a while. I’ve got less time to work on this blog than I used to and in some ways that bothers me. Additionally I feel severely outclassed by the C# expertise I see in the insiders mailing list as well as C# community that I’m almost skeptical I belong there. Then I think about how that might fall into Scott Hanselman’s “imposter syndrome”… then I think that only somebody subject to the Dunning-Kruger effect would say that. Then I think that only a person with imposter syndrome would think they were subject ot the Dunning Kruger effect for thinking they had imposter syndrome, then I think….

Have something to say about this post? Comment!

Tags: ,