4

I have investigated an issue around binary serialization of a IComparable property which causes the following error when the IComparable property is assigned a DateTime:

Binary stream '0' does not contain a valid BinaryHeader.

The following code can produce this issue:

/// <summary>
/// This class is injected with an icomparable object, which is assigned to a property.
/// If serialized then deserializes using binary serialization, an exception is thrown
/// </summary>
[Serializable]
public class SomeClassNotWorking
{
    public SomeClassNotWorking(IComparable property)
    {
        Property = property;
    }

    public IComparable Property;

}

public class Program
{
    static void Main(string[] args)
    {
        // var comparable = new SomeClass<DateTime>(DateTime.Today);
        // here we pass in a datetime type that inherits IComparable (ISerializable also produces the error!!)
        var instance = new SomeClassNotWorking(DateTime.Today);

        // now we serialize
        var bytes = BinaryHelper.Serialize(instance);
        BinaryHelper.WriteToFile("serialisedResults", bytes);

        // then deserialize
        var readBytes = BinaryHelper.ReadFromFile("serialisedResults");
        var obj = BinaryHelper.Deserialize(readBytes);
    }
}

I have resolved the issue by replacing the IComparable property with a type T property which implements IComparable:

/// <summary>
/// This class contains a generic type property which implements IComparable
/// This serializes and deserializes correctly without error
/// </summary>
/// <typeparam name="T"></typeparam>
[Serializable]
public class SomeClass<T> where T : IComparable
{
    public SomeClass(T property)
    {
        Property = property;
    }

    public T Property;
}

This serializes and de-serializes without problems. However, why would serialization of an IComparable property (when that property is a DateTime) cause the issue in the first place, particularly as DateTime supports IComparable? This also happens with ISerializable.

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
mmd
  • 63
  • 1
  • 6
  • It probably is directly related to the fact that you cannot create an instance of an interface. – Bob2Chiv May 09 '12 at 14:39
  • @Bob2Chiv it works when he provides his implementation of IComparable. It's a known bug. – Adriano Repetti May 09 '12 at 14:41
  • @Adriano Interesting, I thought it was because you can serialize an instance of T, but not an instance of IComparable; even if there is a concrete value associated with it, like in this [question](http://stackoverflow.com/questions/3632769/cannot-serialize-member-because-it-is-an-interface). Very nice to know about this bug, however. – Bob2Chiv May 09 '12 at 14:59
  • @Bob2Chiv I still don't understand why it has not been fixed! I guess for compatibility but I can't imagine how. Anyway it _seems_ to happen only for value types. – Adriano Repetti May 09 '12 at 15:21

1 Answers1

4

It's a known bug and it's not fixed: http://connect.microsoft.com/VisualStudio/feedback/details/91177/de-serialization-of-an-instance-of-a-class-implementing-icomparable-does-not-work

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
  • Different value types produce different results / exceptions. If I pass in an int rather than a DateTime I get the following error - SerializationException - End of Stream encountered before parsing was completed. – mmd May 09 '12 at 15:28
  • @mmd yes maybe it depends on how the data is being deserialized but I agree, it's a very _stupid_ thing... – Adriano Repetti May 09 '12 at 15:34
  • A known bug with inconsistent results is not very helpful! Shame that there is no planned fix and that the work involved outweighs the benefits. @Adriano - Thanks for the info and link. – mmd May 09 '12 at 16:00