共用方式為


SYSLIB0051:舊版序列化支援 API 已淘汰

從 .NET 8 開始,下列類型的 API 已淘汰。 在程式碼中呼叫這些方法會導致在編譯時間產生警告 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 相容性需求限制的程式庫。 在此情況下,建議使用 SYSLIB0051 診斷程式碼淘汰您自己的序列化建構函式和 GetObjectData 方法,如下列程式代碼所示。 由於在理想情況下,序列化基礎結構本身之外的任何人都不應呼叫這些 API,因此,淘汰應該僅影響自訂例外狀況型別子類別的其他類型。 它不應以病毒方式影響任何人攔截、建構或使用您自訂例外狀況型別。

    [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>

如需詳細資訊,請參閱隱藏警告

另請參閱