| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot apply [PSerializable] to type '<Type>' because the serializer '<Serializer>' is not visible from '<Type>'. |
Cause
When a [PSerializableAttribute] class derives from a class whose serializer is written by hand, the serializer that PostSharp generates for the derived class is a nested class of <Type> that derives from the serializer of the base class. A class can derive only from a class that it can see, so the serializer of the base class must be visible from <Type>.
PostSharp reports SR0009 on <Type> when the serializer <Serializer> of its base class is not visible from it: typically a private nested class of the base class.
In the following example, EntitySerializer is a private nested class of Entity, so Customer cannot see it.
using System;
using System.IO;
using PostSharp.Serialization;
namespace Errors.SR0009_Error;
[Serializer( typeof(EntitySerializer) )]
public class Entity
{
public int Id { get; set; }
public Entity() { }
// The deserializing constructor, which the serializer of Customer calls.
protected Entity( PortableFormatterConstructorContext context ) { }
private class EntitySerializer : ReferenceTypeSerializer
{
public override object CreateInstance( Type type, IArgumentsReader constructorArguments ) => new Entity();
public override void SerializeObject( object obj, IArgumentsWriter constructorArguments, IArgumentsWriter initializationArguments )
=> initializationArguments.SetValue( "Id", ((Entity) obj).Id );
public override void DeserializeFields( object obj, IArgumentsReader initializationArguments )
=> ((Entity) obj).Id = initializationArguments.GetValue<int>( "Id" );
}
}
[PSerializable]
public class Customer : Entity // The private EntitySerializer is not visible from Customer.
{
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 { Id = 1, Name = "Alice" }, stream );
stream.Position = 0;
var customer = (Customer) formatter.Deserialize( stream );
Console.WriteLine( $"Customer {customer.Id}: {customer.Name}" );
}
}
error SR0009: SR0009_Error.cs(30,14): Cannot apply [PSerializable] to type 'Errors.SR0009_Error.Customer' because the serializer 'Errors.SR0009_Error.Entity.EntitySerializer' is not visible from 'Errors.SR0009_Error.Customer'.
Resolution
Make the serializer of the base class visible from the derived classes, for example protected or public when it is nested in the base class.
In the following example, EntitySerializer is protected, and a Customer is serialized and deserialized with its Id and its Name.
using System;
using System.IO;
using PostSharp.Serialization;
namespace Errors.SR0009_Fixed;
[Serializer( typeof(EntitySerializer) )]
public class Entity
{
public int Id { get; set; }
public Entity() { }
// The deserializing constructor, which the serializer of Customer calls.
protected Entity( PortableFormatterConstructorContext context ) { }
// Protected, so the serializer is visible from Customer.
protected class EntitySerializer : ReferenceTypeSerializer
{
public override object CreateInstance( Type type, IArgumentsReader constructorArguments ) => new Entity();
public override void SerializeObject( object obj, IArgumentsWriter constructorArguments, IArgumentsWriter initializationArguments )
=> initializationArguments.SetValue( "Id", ((Entity) obj).Id );
public override void DeserializeFields( object obj, IArgumentsReader initializationArguments )
=> ((Entity) obj).Id = initializationArguments.GetValue<int>( "Id" );
}
}
[PSerializable]
public class Customer : Entity
{
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 { Id = 1, Name = "Alice" }, stream );
stream.Position = 0;
var customer = (Customer) formatter.Deserialize( stream );
Console.WriteLine( $"Customer {customer.Id}: {customer.Name}" );
}
}
Customer 1: Alice
See Also
Reference
PSerializableAttribute
ReferenceTypeSerializer
SerializerAttribute
Other Resources