16 December 2008

[Serializable] does not inherit (aka RTFM)

Of course, everybody knows that if you want to serialize an object, you need to decorate the class with the [Serializable] attribute. Right? Well, yes, and so do I, but I ran into a snag today: it is an attribute, not a property so it does not inherit. If you consider the following code
using System;

namespace demo
{
    [Serializable]
    public class BaseClass
    {
        public string AProperty { get; set; }
    }

    public class ChildClass : BaseClass
    {
        public string AnotherProperty { get; set; }
    }
}
you will find that Childclass will not serialize with BinaryFormatter, although its base class will. This is of course quite evident, but a more interesting gotcha occurs when you add a third class:
    [Serializable]
    public class ChildClass2 : ChildClass
    {
        public string FinalProperty { get; set; }
    }
This won't serialize either, because halfway up it's class hierarchy there's a non-serializable class. In plain vanilla .NET this will generate an "Failed to serialize. Reason: Type 'demo.ChildClass' in Assembly 'bla bla bla' is not marked as serializable", precisely pinpointing the problem. If it happens (as in my case) deep down inside a CSLA dataportal, all you get is an error message like
System.ServiceModel.CommunicationException: The underlying connection was closed: The connection was closed unexpectedly. ---> System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly.
And you might spend quite some time finding out it is caused by a non-serializable class somewhere in your class hierarchy. So, check your attributes, folkes ;-) Or run FxCop (and read the warnings)

No comments: