CA2229: Implement serialization constructors

Property Value
Rule ID CA2229
Title Implement serialization constructors
Category Usage
Fix is breaking or non-breaking Non-breaking
Enabled by default in .NET 9 No

Note

This rule was removed in .NET 8 because it conflicts with SYSLIB0051: Legacy serialization support APIs are obsolete.

Cause

The type implements the System.Runtime.Serialization.ISerializable interface, is not a delegate or interface, and one of the following conditions is true:

  • The type does not have a constructor that takes a SerializationInfo object and a StreamingContext object (the signature of the serialization constructor).

  • The type is unsealed and the access modifier for its serialization constructor is not protected (family).

  • The type is sealed and the access modifier for its serialization constructor is not private.

Rule description

This rule is relevant for types that support custom serialization. A type supports custom serialization if it implements the ISerializable interface. The serialization constructor is required to deserialize, or recreate, objects that have been serialized using the ISerializable.GetObjectData method.

How to fix violations

To fix a violation of this rule, implement the serialization constructor. For a sealed class, make the constructor private; otherwise, make it protected.

When to suppress warnings

Do not suppress a violation of the rule. The type will not be deserializable, and will not function in many scenarios.

Example

The following example shows a type that satisfies the rule.

[Serializable]
public class SerializationConstructorsRequired : ISerializable
{
    private int n1;

    // This is a regular constructor.
    public SerializationConstructorsRequired()
    {
        n1 = -1;
    }
    // This is the serialization constructor.
    // Satisfies rule: ImplementSerializationConstructors.

    protected SerializationConstructorsRequired(
       SerializationInfo info,
       StreamingContext context)
    {
        n1 = (info.GetValue(nameof(n1), typeof(int)) != null) ?
            (int)info.GetValue(nameof(n1), typeof(int))! :
            -1;
    }

    // The following method serializes the instance.
    void ISerializable.GetObjectData(SerializationInfo info,
       StreamingContext context)
    {
        info.AddValue(nameof(n1), n1);
    }
}

CA2237: Mark ISerializable types with SerializableAttribute

See also