SYSLIB0051: APIs de suporte à serialização herdada estão obsoletas
Os tipos de APIs a seguir estão obsoletas, começando no .NET 8. Chamá-los no código gera aviso SYSLIB0051
em tempo de compilação.
- Todos os construtores de serialização públicos ou protegidos que seguem o padrão
.ctor(SerializationInfo, StreamingContext)
. Um exemplo desse construtor é Exception(SerializationInfo, StreamingContext). - Todas as implementações implícitas do método ISerializable.GetObjectData(SerializationInfo, StreamingContext), por exemplo, System.Exception.GetObjectData(SerializationInfo, StreamingContext).
- Todas as implementações implícitas do método IObjectReference.GetRealObject(StreamingContext), por exemplo, System.Reflection.ParameterInfo.GetRealObject(StreamingContext).
Para obter uma lista completa das APIs afetadas, confira APIs obsoletas – SYSLIB0051.
Solução alternativa
Se você criou um tipo personalizado derivado de System.Exception, considere se realmente precisa que ele seja serializável. É provável que você não precise que ele seja serializável, pois a serialização de exceção destina-se principalmente à comunicação remota e o suporte para a comunicação remota foi descartado no .NET Core 1.0.
Se o tipo de exceção personalizado for definido como o mostrado no snippet de código a seguir, basta remover o atributo
[Serializable]
, o construtor de serialização e a substituição de método GetObjectData(SerializationInfo, StreamingContext).[Serializable] // Remove this attribute. public class MyException : Exception { public MyException() { } public MyException(string message) : base(message) { } public MyException(string message, Exception inner) : base(message, inner) { } // Remove this constructor. protected MyException(SerializationInfo info, StreamingContext context) : base(info, context) { // ... } // Remove this method. public override void GetObjectData(SerializationInfo info, StreamingContext context) { // ... base.GetObjectData(info, context); } }
Pode haver casos em que você não possa remover essas APIs de seu tipo de exceção personalizado, por exemplo, se você produzir uma biblioteca restrita por requisitos de compatibilidade de API. Nesse caso, a recomendação é tornar obsoleto seu construtor de serialização e os métodos
GetObjectData
usando o código de diagnósticoSYSLIB0051
, conforme mostrado no código a seguir. Como idealmente ninguém fora da própria infraestrutura de serialização deve chamar essas APIs, a obsolescência só deve afetar outros tipos que definem subclasses em seu tipo de exceção personalizado. Isso não deve afetar ninguém que captura, constrói ou usa seu tipo de exceção personalizado.[Serializable] public class MyException : Exception { public MyException() { } public MyException(string message) : base(message) { } public MyException(string message, Exception inner) : base(message, inner) { } [Obsolete(DiagnosticId = "SYSLIB0051")] // Add this attribute to the serialization ctor. protected MyException(SerializationInfo info, StreamingContext context) : base(info, context) { // ... } [Obsolete(DiagnosticId = "SYSLIB0051")] // Add this attribute to GetObjectData. public override void GetObjectData(SerializationInfo info, StreamingContext context) { // ... base.GetObjectData(info, context); } }
Se usar o .NET Framework e o .NET 8+ como destino cruzado, poderá usar uma instrução
#if
para aplicar a obsolescência condicionalmente. Essa é a mesma estratégia que a equipe do .NET usa na base de código de bibliotecas do .NET ao definir runtimes como destino.[Serializable] public class MyException : Exception { // ... #if NET8_0_OR_GREATER [Obsolete(DiagnosticId = "SYSLIB0051")] // add this attribute to the serialization ctor #endif protected MyException(SerializationInfo info, StreamingContext context) : base(info, context) { // ... } #if NET8_0_OR_GREATER [Obsolete(DiagnosticId = "SYSLIB0051")] // add this attribute to GetObjectData #endif public override void GetObjectData(SerializationInfo info, StreamingContext context) { // ... base.GetObjectData(info, context); } }
Se você declarou um tipo que define uma subclasse de um tipo .NET atribuído com
[Serializable]
e está recebendo avisosSYSLIB0051
, siga as diretrizes para tipos de exceção personalizados no ponto anterior.
Dica
Se o tipo personalizado [Serializable]
não definir uma subclasse de um tipo .NET, você não verá avisos SYSLIB0051
. No entanto, recomendamos não anotar seu tipo dessa maneira, pois bibliotecas de serialização modernas como System.Text.Json
não exigem isso. Considere remover o atributo [Serializable]
e a interface ISerializable
. Em vez disso, confie em sua biblioteca de serialização para acessar objetos do tipo por meio das propriedades públicas, em vez de campos privados.
Suprimir um aviso
Se for necessário usar as APIs obsoletas, você poderá suprimir o aviso no código ou no arquivo de projeto.
Para suprimir apenas uma violação única, adicione as diretivas de pré-processador ao arquivo de origem para desabilitar e, em seguida, reabilite o aviso.
// Disable the warning.
#pragma warning disable SYSLIB0051
// Code that uses obsolete API.
// ...
// Re-enable the warning.
#pragma warning restore SYSLIB0051
Para suprimir todos os avisos SYSLIB0051
no projeto, adicione uma propriedade <NoWarn>
ao arquivo de projeto.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
...
<NoWarn>$(NoWarn);SYSLIB0051</NoWarn>
</PropertyGroup>
</Project>
Para obter mais informações, confira Suprimir avisos.