0

The title says pretty much what I would like to know. I have data which was binary serialized and now I'm reading it again (class name remains the same) and I would like to know if the serializer misses something because, for example, a private backing field might have been renamed.

I did the following refactoring:

private string descriptionField;
public string Description
{
  get { return this.descriptionField; }
}

to

public string Description { get; private set; }

As stated in in this article this won't work. But I really would like to know if there is a way to detect if the class does not match the serialized data.

I do not want to do the serialization myself via implementing ISerializable because the class and its properties is quite large and might be changed. I'd prefer a easier solution =)

Faris Zacina
  • 14,056
  • 7
  • 62
  • 75
DerApe
  • 3,097
  • 2
  • 35
  • 55
  • Catch the exception it'll throw but you can't do anything for fields that has not been serialized (just provide a meaningful default value). Of course if you implement `ISerializable` you'll have greater control about that (you know what you're reading: if one field isn't stored then it won't be initialized, just check before each read). – Adriano Repetti Oct 22 '14 at 15:09
  • The problem is, it wont throw an exception, the changed field names are just initialized with its default value – DerApe Oct 23 '14 at 06:09
  • If you **rename** something then it will throw because old variable name can't be found. Nothing will happen if you **add** something. In this case they'll just have default value. It's here where you can do something implementing ISerializable. In constructor you will manually read fields and you can check if they're available in serialized data. If not you don't read them but you also know it (and it's also a pretty raw way to manage versioning). – Adriano Repetti Oct 23 '14 at 07:30
  • As I said, it does not throw an exception with the example I provided. A implicit renaming is done because the backing field will be generated by the compiler in the background (I used the `BinaryFormatter`). Also I do not want to use `ISerializable` because the class is quite large – DerApe Oct 23 '14 at 07:37
  • Think about `OptionalFieldAttribute`! It exists because `BinaryFormatter` _may_ throw in that case. It's just not its default behavior, to enable it set `BinaryFormatter.AssemblyFormat` to `FormatterAssemblyStyle.Full`. That said it's not the _right_ way to manage this stuff...`ISerializable` is, even if it's pretty annoying to write (well, `BinaryFormatter` - but in general serialization - isn't the right pick to persist application data across versions unless you're doing pretty trivial stuffs). – Adriano Repetti Oct 23 '14 at 08:19
  • Once upon a time I was bored, so I build a BinaryFormatterStreamReader which could parse the output from a BinaryFormatter into dictionaries, so I could parse serialized content without having references to the types that was serialized. You could use this just to check what content is present in the stream to verify that you've got everything. https://github.com/devhost/Corelicious/tree/master/Corelicious/Serialization – sisve Oct 23 '14 at 08:46

1 Answers1

1

But I really would like to know if there is a way to detect if the class does not match the serialized data?

One way to detect it would be to serialize the existing class with the same data as in the previous serialized file and then compare the digital fingerprints of the previous and current serialized files.

I do not want to do the serialization myself via implementing ISerializable because the class and its properties is quite large and might be changed.

Since you are using the BinaryFormatter and dealing with potentially significant versioning issues, i think your only option is to implement ISerializable and handle deserialization yourself whether you like it or not.

Faris Zacina
  • 14,056
  • 7
  • 62
  • 75
  • I agree. How can the deserializer possibly know what you renamed? Your best bet is to do it yourself. – Alex Oct 23 '14 at 08:41
  • I think I will take your first option. In our case we have indexed data serialized to the hard drive to save server calls. So we will do that check on application startup which is okay for one file. Thanks =) – DerApe Oct 23 '14 at 08:49