Implement ISerializable correctly
TypeName |
ImplementISerializableCorrectly |
CheckId |
CA2240 |
Category |
Microsoft.Usage |
Breaking Change |
NonBreaking |
Cause
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.
Rule Description
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.
How to Fix Violations
To fix a violation of this rule, make the GetObjectData method visible and overridable and make sure all instance fields are included in the serialization process or explicitly marked with the NonSerializedAttribute attribute.
When to Exclude Warnings
Do not exclude a warning from this rule.
Example
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.
Related Rules
Call base class methods on ISerializable types
Implement serialization constructors
Implement serialization methods correctly
Mark all non-serializable fields
Mark ISerializable types with serializable
Provide deserialization methods for optional fields