Thursday, August 21, 2008

XMLSerializer, part 2

After spending more time fixing bugs and digging into XMLSerializer (see my previous post), I've come the the following conclusions:
  1. I'm still satisfied with my design where I split the "data" into a separate class. It makes it much easier to quickly see what is being serialized and what is not. If I hadn't done this, I would have reorganized the fields in my objects to put all the serializable fields together, so I could put all the unserializable fields (with their corresponding noisy attribute tags) in a separate section of the class definition.
  2. I figured out my problem (mentioned in bullet item 3 in the previous post). I had not provided a default value for an enum in the class definition. Once I did that, the uninformative error message went away and my object was sitting happily on disk.

On to the next learning experience...

Friday, August 1, 2008

Dealing with .NET XMLSerializer

I've found that the clearest (e.g., fewest lines of code) and quickest (e.g., fewest surprises) way to deal with XMLSerializer is to create "data" classes. These instances of these classes are then owned and used by instances of "code" classes. This gets around the following issues:
  • XMLSerializer will only serialize Public fields. It isn't good programming practice to have to declare fields as public. To reduce this ugliness, I moved the serializable fields down into the data class and made the reference to the data class Private. I then put Public Property(s) on the code class that reference the field in the data class.
  • XMLSerializer doesn't support hashtables, which I find much more useful (and natural in many cases). I used hashtables on the code class. I then added code to a GetSerializable method that sits on the code class that populate the corresponding array on the data class on demand.
  • XMLSerializer doesn't provide very good error messages. My first attempt at changing a class to user XMLSerializer hit many problems with many different fields in the existing class. Using a data class, I don't have to figure out all the problems all at once. I can move fields from the code class to the data class incrementally, and figure out the particular problem with that field before moving on to the next. One specific example of this are issues with using Public Property. I haven't figured out what they are yet, but I'm suspicious of either:
  • Public Properties that aren't simple "return" and "assignment" Properties.
  • Public Properties that wrap a field that is also Public.

The downside is that I have a few extra public fields on various objects that are only used for serialization. The upside is fewer lines of code and a (somewhat) straightforward paradigm for dealing with XMLSerializer.