Implement ISerializable correctly
| TypeName | ImplementISerializableCorrectly |
| CheckId | CA2240 |
| Category | Microsoft.Usage |
| Breaking Change | NonBreaking |
An externally visible type is assignable to the System.Runtime.Serialization.ISerializable interface and one of the following conditions is true:
-
The type inherits but does not override the System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext) method and the type declares instance fields that are not marked with the System.NonSerializedAttribute attribute.
-
The type is not sealed and the type implements a GetObjectData method that is not externally visible and overridable.
Instance fields that are declared in a type that inherits the System.Runtime.Serialization.ISerializable interface are not automatically included in the serialization process. To include the fields, the type must implement the GetObjectData method and the serialization constructor. If the fields should not be serialized, apply the NonSerializedAttribute attribute to the fields to explicitly indicate the decision.
In types that are not sealed, implementations of the GetObjectData method should be externally visible, so that the method can be called by derived types, and overridable.
The following example shows a derived serializable type with a serializable field that violates the rule and a type that satisfies the rule by correctly implementing the GetObjectData method.
The example above shows how to implement ISerializable method. In C#, it is often better to implement ISerializable.GetObjectData method explicitly and have it call a protected method. In Visual Basic, implement ISerializable.GetObjectData directly using a protected method. This saves you implementing methods in the public API that consumers will never need to call directly.
The following example shows a class that does this.
To test if ISerializable has been implemented correctly create a helper method, a method that tests the serialization of an object by serializing to and then desterilizing from a binary stream directly in memory. This will call both the serialization constructor and ISerializable.GetObjectData implementation.
The example above allows you to do the following (this block uses the Book class from above).
The above example outputs the following:
Output
This is the book's text.