SYSLIB0050:基于格式化程序的序列化已过时
从 .NET 8 开始,以下 API 已过时。 在代码中调用这些方法会在编译时生成警告 SYSLIB0050
。
- System.Runtime.Serialization.FormatterConverter
- System.Runtime.Serialization.FormatterServices
- System.Runtime.Serialization.IFormatterConverter
- System.Runtime.Serialization.IObjectReference
- System.Runtime.Serialization.ISafeSerializationData
- System.Runtime.Serialization.ISerializationSurrogate
- System.Runtime.Serialization.ISurrogateSelector
- System.Runtime.Serialization.ObjectIDGenerator
- System.Runtime.Serialization.ObjectManager
- System.Runtime.Serialization.SafeSerializationEventArgs
- System.Runtime.Serialization.SerializationObjectManager
- System.Runtime.Serialization.StreamingContextStates
- System.Runtime.Serialization.SurrogateSelector
- System.Runtime.Serialization.Formatters.FormatterAssemblyStyle
- System.Runtime.Serialization.Formatters.FormatterTypeStyle
- System.Runtime.Serialization.Formatters.IFieldInfo
- System.Runtime.Serialization.Formatters.TypeFilterLevel
- System.Type.IsSerializable
- System.Reflection.FieldAttributes.NotSerialized
- System.Reflection.FieldInfo.IsNotSerialized
- System.Reflection.TypeAttributes.Serializable
- System.Runtime.Serialization.ISerializable.GetObjectData(SerializationInfo, StreamingContext)
- SerializationInfo(Type, IFormatterConverter, Boolean)
- SerializationInfo(Type, IFormatterConverter)
- StreamingContext(StreamingContextStates, Object)
- StreamingContext(StreamingContextStates)
解决方法
如果使用的是 FormatterServices.GetUninitializedObject(Type),请改用 RuntimeHelpers.GetUninitializedObject(Type)。
如果对 .NET Framework 和新式 .NET 进行交叉编译,则可以使用
#if
语句选择性地调用相应的 API,如以下代码片段所示。Type typeToInstantiate; #if NET5_0_OR_GREATER object obj = System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject(typeToInstantiate); #else object obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeToInstantiate); #endif
如果要编写序列化库,强烈建议不要使用支持旧序列化基础结构的序列化库(
[Serializable]
和ISerializable
)。 新式序列化库应具有基于某种类型的公共 API 而不是其专用实现详细信息的策略。 如果使序列化程序基于这些实现详细信息,并将其与ISerializable
和鼓励在序列化有效负载中嵌入类型名称的其他机制紧密关联,这可能会导致出现使用 BinaryFormatter 和相关类型时的反序列化风险中所述的问题。如果序列化库必须一直与旧序列化基础结构兼容,那么你可以轻松取消旧序列化 API 过时。
抑制警告
如果必须使用已过时的 API,可在代码或项目文件中禁止显示警告。
若只想抑制单个冲突,请将预处理器指令添加到源文件以禁用该规则,然后重新启用警告。
// Disable the warning.
#pragma warning disable SYSLIB0050
// Code that uses obsolete API.
// ...
// Re-enable the warning.
#pragma warning restore SYSLIB0050
若要禁止显示项目中的所有 SYSLIB0050
警告,请将属性 <NoWarn>
添加到项目文件。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
...
<NoWarn>$(NoWarn);SYSLIB0050</NoWarn>
</PropertyGroup>
</Project>
有关详细信息,请参阅取消警告。