| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot apply [PSerializable] to type '<Type>' because its base type is not serializable: it has neither a [PSerializable] or [Serializer] attribute nor a nested Serializer class. Apply [PSerializable] to the base type. |
Cause
[PSerializableAttribute] generates a serializer for <Type> that serializes the fields declared in <Type>, and extends the serializer of the base type for the fields that the base type declares. The base type must therefore have a serializer, given by one of:
- [PSerializableAttribute], which generates it;
- [SerializerAttribute], which names a serializer written by hand, or no serializer with
[Serializer(null)]when the base type has no state to serialize; - a nested class named
Serializer, written by hand.
The base types object, ValueType, Attribute and MarshalByRefObject do not need a serializer. PostSharp reports SR0006 when the direct base type of <Type> is another type that has none of the three. This includes most classes of .NET and of other libraries.
In the following example, Customer is [PSerializableAttribute], but its base class Entity is not.
using System;
using System.IO;
using PostSharp.Serialization;
namespace Errors.SR0006_Error;
public class Entity
{
public int Id { get; set; }
}
[PSerializable]
public class Customer : Entity // Entity is not serializable.
{
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 SR0006: SR0006_Error.cs(13,14): Cannot apply [PSerializable] to type 'Errors.SR0006_Error.Customer' because its base type is not serializable: it has neither a [PSerializable] or [Serializer] attribute nor a nested Serializer class. Apply [PSerializable] to the base type.
Resolution
- Apply [PSerializableAttribute] to the base type. PostSharp then generates its serializer, which the serializer of the derived type extends.
- When the base type has no state to serialize, mark it with
[Serializer(null)], and give it a parameterless constructor that the derived type can access. - When you cannot change the base type, for example because it is a class of another library, do not derive from it: keep an instance of it in a field, write a serializer for its type, and declare this serializer with ImportSerializerAttribute.
In the following example, Entity is [PSerializableAttribute], and a Customer is serialized and deserialized with its Id and its Name.
using System;
using System.IO;
using PostSharp.Serialization;
namespace Errors.SR0006_Fixed;
// PostSharp generates the serializer of the base class too.
[PSerializable]
public class Entity
{
public int Id { get; set; }
}
[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
SerializerAttribute
PortableFormatter
Other Resources