Open sandboxFocusImprove this doc

SR0003: Base Constructor Not Accessible from a PSerializable Type

Severity Error
Reported by PostSharp
Message Cannot apply [PSerializable] to type '<Type>' because the base constructor '<BaseConstructor>' is not accessible from '<Type>'.

Cause

[PSerializableAttribute] generates a deserializing constructor in <Type>, which PortableFormatter calls to create the instance before it restores its fields. This constructor calls <BaseConstructor>, a constructor of the base type:

  • the deserializing constructor of the base type, which has a single parameter of type PortableFormatterConstructorContext, when the base type has one;
  • otherwise, when the base type is marked [Serializer(null)] because it has no state to serialize, its parameterless constructor.

PostSharp reports SR0003 when <BaseConstructor> is not accessible from <Type>, for example when it is private, or internal in another assembly. PostSharp reports the message on <Type>, not on the constructor of the base type, and shows <BaseConstructor> without its parameters, as Entity.#ctor.

In the following example, Entity has no serializer, and its parameterless constructor is private, so the deserializing constructor of Customer cannot call it.

using System;
using System.IO;
using PostSharp.Serialization;

namespace Errors.SR0003_Error;

// Entity has no state to serialize, so it has no serializer.
[Serializer( null )]
public abstract class Entity
{
    // Derived classes must give a name, which this constructor does not check.
    private Entity()
    {
    }

    protected Entity( string name )
    {
        if ( string.IsNullOrEmpty( name ) )
        {
            throw new ArgumentException( "The name cannot be empty.", nameof(name) );
        }
    }
}

[PSerializable]
public class Customer : Entity // The parameterless constructor of Entity is private.
{
    public Customer( string name ) : base( name )
    {
        this.Name = name;
    }

    public string Name { get; set; }
}

public static class Program
{
    public static void Main()
    {
        var formatter = new PortableFormatter();
        var stream = new MemoryStream();
        formatter.Serialize( new Customer( "Alice" ), stream );
        stream.Position = 0;

        var customer = (Customer) formatter.Deserialize( stream );
        Console.WriteLine( $"Customer {customer.Name}" );
    }
}
error SR0003: SR0003_Error.cs(26,14): Cannot apply [PSerializable] to type 'Errors.SR0003_Error.Customer' because the base constructor 'Errors.SR0003_Error.Entity.#ctor' is not accessible from 'Errors.SR0003_Error.Customer'.

Resolution

Make <BaseConstructor> accessible from the derived type: protected is enough. When the base type is in another assembly, internal is not enough.

In the following example, the parameterless constructor of Entity is protected, and a Customer is serialized and deserialized with PortableFormatter.

using System;
using System.IO;
using PostSharp.Serialization;

namespace Errors.SR0003_Fixed;

// Entity has no state to serialize, so it has no serializer.
[Serializer( null )]
public abstract class Entity
{
    // The deserializing constructor of a derived class calls this constructor.
    protected Entity()
    {
    }

    protected Entity( string name )
    {
        if ( string.IsNullOrEmpty( name ) )
        {
            throw new ArgumentException( "The name cannot be empty.", nameof(name) );
        }
    }
}

[PSerializable]
public class Customer : Entity
{
    public Customer( string name ) : base( name )
    {
        this.Name = name;
    }

    public string Name { get; set; }
}

public static class Program
{
    public static void Main()
    {
        var formatter = new PortableFormatter();
        var stream = new MemoryStream();
        formatter.Serialize( new Customer( "Alice" ), stream );
        stream.Position = 0;

        var customer = (Customer) formatter.Deserialize( stream );
        Console.WriteLine( $"Customer {customer.Name}" );
    }
}
Customer Alice

See Also

Reference

PSerializableAttribute
SerializerAttribute
PortableFormatter

Other Resources

Understanding Aspect Serialization