40

Based on my understanding, SerializableAttribute provides no compile time checks, as it's all done at runtime. If that's the case, then why is it required for classes to be marked as serializable?

Couldn't the serializer just try to serialize an object and then fail? Isn't that what it does right now? When something is marked, it tries and fails. Wouldn't it be better if you had to mark things as unserializable rather than serializable? That way you wouldn't have the problem of libraries not marking things as serializable?

Odrade
  • 7,409
  • 11
  • 42
  • 65
kay.one
  • 7,622
  • 6
  • 55
  • 74
  • possible duplicate of [Why do you have to mark a class with the attribute \[serializable\]?](http://stackoverflow.com/questions/2595104/why-do-you-have-to-mark-a-class-with-the-attribute-serializable) – nawfal Jul 10 '14 at 09:57
  • You could try to automatically add the attributes for all your classes using [postsharp](https://www.postsharp.net/). A similar use is shown in this Question: http://stackoverflow.com/questions/7851365/how-to-inject-an-attribute-using-a-postsharp-attribute – Markus Weber Feb 17 '16 at 17:51

2 Answers2

46

As I understand it, the idea behind the SerializableAttribute is to create an opt-in system for binary serialization.

Keep in mind that, unlike XML serialization, which uses public properties, binary serialization grabs all the private fields by default.

Not only this could include operating system structures and private data that is not supposed to be exposed, but deserializing it could result in corrupt state that can crash an application (silly example: a handle for a file open in a different computer).

Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154
23

This is only a requirement for BinaryFormatter (and the SOAP equivalent, but nobody uses that). Diego is right; there are good reasons for this in terms of what it does, but it is far from the only option - indeed, personally I only recommend BinaryFormatter for talking between AppDomains - it is not (IMO) a good way to persist data (to disk, in cache, to a database BLOB, etc).

If this behaviour causes you trouble, consider using any of the alternatives:

  • XmlSerializer, which works on public members (not just the fields), but demands a public parameterless constructor and public type
  • DataContractSerializer, which can work fully opt-in (using [DataContract]/[DataMember]), but which can also (in 3.5 and above) work against the fields instead

Also - for a 3rd-party option (me being the 3rd party); protobuf-net may have options here; "v2" (not fully released yet, but available as source) allows the model (which members to serialize, etc) to be described independently of the type, so that it can be applied to types that you don't control. And unlike BinaryFormatter the output is version-tolerant, known public format, etc.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • awesome. Wonderful summary of the choices you have for serializing in c# with their advantages and their disadvantages. Exactly what I was looking for during the last week... Merci Marc. – Arthis Jun 29 '12 at 12:57