SYSLIB0051: Las API de compatibilidad con la serialización heredada están obsoletas
Los siguientes tipos de API están obsoletos a partir de .NET 8. Si se los llama en el código, se genera la advertencia SYSLIB0051
en tiempo de compilación.
- Todos los constructores de serialización públicos o protegidos que siguen el patrón
.ctor(SerializationInfo, StreamingContext)
. Un ejemplo de este constructor es Exception(SerializationInfo, StreamingContext). - Todas las implementaciones implícitas del método ISerializable.GetObjectData(SerializationInfo, StreamingContext); por ejemplo, System.Exception.GetObjectData(SerializationInfo, StreamingContext).
- Todas las implementaciones implícitas del método IObjectReference.GetRealObject(StreamingContext); por ejemplo, System.Reflection.ParameterInfo.GetRealObject(StreamingContext).
Para obtener una lista completa de las API afectadas, consulte API obsoletas: SYSLIB0051.
Solución alternativa
Si ha creado un tipo personalizado derivado de System.Exception, considere si realmente necesita que sea serializable. Es probable que no necesite que sea serializable, ya que la serialización de excepciones está pensada principalmente para admitir la comunicación remota, y la compatibilidad con la comunicación remota se quitó en .NET Core 1.0.
Si el tipo de excepción personalizado se define como el que se muestra en el siguiente fragmento de código, simplemente quite el atributo
[Serializable]
, el constructor de serialización y la invalidación del 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); } }
Puede haber casos en los que no pueda quitar estas API del tipo de excepción personalizado, por ejemplo, si genera una biblioteca restringida por los requisitos de compatibilidad de API. En este caso, la recomendación es dejar obsoleto su propio constructor de serialización y los métodos
GetObjectData
mediante el código de diagnósticoSYSLIB0051
, como se muestra en el código siguiente. Como lo ideal es que nadie fuera de la infraestructura de serialización llame a estas API, la obsolescencia solo debería afectar a otros tipos que conviertan en subclase el tipo de excepción personalizado. No debería afectar significativamente a nadie en la detección, la construcción o el uso del tipo de excepción 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); } }
Si tiene un destino cruzado para .NET Framework y .NET 8+, puede usar una instrucción
#if
para aplicar la obsolescencia condicionalmente. Esta es la misma estrategia que el equipo de .NET usa en la base de código de las bibliotecas de .NET al dirigirse de forma cruzada a los tiempos de ejecución.[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); } }
Si ha declarado un tipo que convierte en subclase un tipo de .NET con el atributo
[Serializable]
y que recibe advertenciasSYSLIB0051
, siga las instrucciones para los tipos de excepción personalizados en el punto anterior.
Sugerencia
Si el tipo personalizado [Serializable]
no convierte en subclase un tipo de .NET, no verá advertencias SYSLIB0051
. Sin embargo, se recomienda anotar el tipo de esta manera, ya que las bibliotecas de serialización modernas, como System.Text.Json
, como no lo requieren. Considere la posibilidad de quitar el atributo [Serializable]
y la interfaz ISerializable
. En su lugar, confíe en la biblioteca de serialización para acceder a los objetos del tipo a través de sus propiedades públicas en lugar de sus campos privados.
Supresión de una advertencia
Si tiene que seguir usando las API obsoletas, puede suprimir la advertencia en el código o en el archivo de proyecto.
Para suprimir solo una infracción, agregue directivas de preprocesador al archivo de origen para deshabilitar y luego volver a habilitar la advertencia.
// Disable the warning.
#pragma warning disable SYSLIB0051
// Code that uses obsolete API.
// ...
// Re-enable the warning.
#pragma warning restore SYSLIB0051
Para suprimir todas las advertencias SYSLIB0051
del proyecto, agregue una propiedad <NoWarn>
al archivo del proyecto.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
...
<NoWarn>$(NoWarn);SYSLIB0051</NoWarn>
</PropertyGroup>
</Project>
Para obtener más información, vea Suprimir advertencias.