dougherty distilled

Bryan Dougherty's thoughts on technology and software development.
in

September 2006 - Posts

Custom Serialization and the Misbehaving Dictionary

Background

I recently needed to implement custom serialization in a class that we'll call MyCollection for simplicity.  The class supported a number of things including providing a Dictionary like interface as well as binding support.  Not surprisingly it maintained a couple collections including a Dictionary(Of TKey, TValue) and a BindingList(Of T), the latter exposing events needed for binding to a grid. 

The Problem

Since I was using binary serialization, serializing the BindingList would be problematic since any objects that hook the BindingList's events would also be serialized.  That includes a BindingSource object which doesn't like to be serialized.  Okay.  No problem.  All I'd need to do is only serialize out my Dictionary, and then rehydrate the BindingList after serialization.

I can prevent serialization of my BindingList by decorating the private member with the <NonSerialized()> attribute. Then using the new <OnDeserialized()> attribute that is part of the .NET 2.0 Framework, this would be easy.  Just create a method in MyCollection of the correct signature, decorate it with this attribute, and write a quick loop to add from the Dictionary to the BindingList.  That easy, right?

Enter the Misbehaving Dictionary

For some reason, the Dictionary is not all quite there when my method gets called.  It's there, but empty.  But if I check it after the serialization is all done (which I thought my method was doing), it IS filled with my objects.  I didn't get it. I tried some simple examples with non-Dictionary classes out and they all work fine.  Then I found empathy, or is it sympathy...well, at least I found someone with my problem:

http://forums.lhotka.net/forums/5495/ShowThread.aspx

Happy to find that I wasn't crazy, I came up with a workaround.  Again using custom serialization attributes, this time the <OnSerializing()> attribute, I can force the serializer to call a method that will copy my Dictionary's keys and values into arrays which are members that will be serialized.  Then during deserialization, I can rebuild my Dictionary based on the keys and then I'm back to where I wanted to be: able to rehydrate my BindingList from my Dictionary.  A little bit of a pain in the butt, but it works nicely.