SYSLIB0051. Устаревшие API-интерфейсы поддержки сериализации устарели

Следующие типы API устарели, начиная с .NET 8. При вызове их в коде выдается предупреждение SYSLIB0051 во время компиляции.

Полный список затронутых API см. в разделе "Устаревшие API- SYSLIB0051".

Обходное решение

  • Если вы создали пользовательский тип, производный от System.Exception, рассмотрите, нужно ли сериализовать его. Скорее всего, вам не нужно сериализовать его, так как сериализация исключений в основном предназначена для поддержки удаленного взаимодействия, а поддержка удаленного взаимодействия была удалена в .NET Core 1.0.

    Если настраиваемый тип исключения определен, как показано в следующем фрагменте кода, просто удалите [Serializable] атрибут, конструктор сериализации и 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);
        }
    }
    

    Могут возникнуть случаи, когда невозможно удалить эти API из пользовательского типа исключения, например, если вы создаете библиотеку, ограниченную требованиями совместимости API. В этом случае рекомендация заключается в том, чтобы устаревшие собственные конструкторы сериализации и GetObjectData методы с помощью SYSLIB0051 диагностического кода, как показано в следующем коде. Так как в идеале никто за пределами самой инфраструктуры сериализации не должен вызывать эти API, obsoletion должен влиять только на другие типы, которые подклассы настраиваемого типа исключения. Он не должен вирусно влиять ни на кого ловить, создавать или иначе использовать настраиваемый тип исключения.

    [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);
        }
    }
    

    Если вы используете перекрестный целевой объект для платформа .NET Framework и .NET 8+, можно использовать инструкцию #if для условного применения обсоля. Это та же стратегия, что команда .NET использует в базе кода библиотек .NET при перекрестной целевой среде выполнения.

    [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);
        }
    }
    
    
  • Если вы объявили тип, который подклассирует тип .NET, который связан с [Serializable] и вы получаете SYSLIB0051 предупреждения, следуйте указаниям по пользовательским типам исключений в предыдущей точке маркера.

Совет

[Serializable] Если настраиваемый тип не классирует тип .NET, вы не увидите SYSLIB0051 предупреждения. Тем не менее, рекомендуется рекомендовать аннотирование типа таким образом, так как современные библиотеки сериализации, как System.Text.Json и не требуют их. Рассмотрите возможность удаления атрибута [Serializable]ISerializable и интерфейса. Вместо этого следует полагаться на библиотеку сериализации для доступа к объектам типа через его общедоступные свойства, а не частные поля.

Отключение предупреждений

Если необходимо использовать устаревшие API, вы можете отключить предупреждение в коде или в файле проекта.

Чтобы отключить только одно нарушение, добавьте директивы препроцессора в исходный файл, чтобы отключить и повторно включить предупреждение.

// Disable the warning.
#pragma warning disable SYSLIB0051

// Code that uses obsolete API.
// ...

// Re-enable the warning.
#pragma warning restore SYSLIB0051

Чтобы отключить все SYSLIB0051 предупреждения в проекте, добавьте <NoWarn> свойство в файл проекта.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
   ...
   <NoWarn>$(NoWarn);SYSLIB0051</NoWarn>
  </PropertyGroup>
</Project>

Дополнительные сведения см. в разделе Отключение предупреждений.

См. также