Compartilhar via


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.

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óstico SYSLIB0051, 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 avisos SYSLIB0051, 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.

Confira também