Condividi tramite


SYSLIB0051: Le API di supporto per la serializzazione legacy sono obsolete

I tipi di API seguenti sono obsoleti, a partire da .NET 8. La loro chiamata nel codice genera un avviso SYSLIB0051 in fase di compilazione.

Per un elenco completo delle API interessate, vedere API obsolete - SYSLIB0051.

Soluzione alternativa

  • Se è stato creato un tipo personalizzato derivato da System.Exception, valutare se è effettivamente necessario che sia serializzabile. È probabile che non sia necessario serializzarlo, perché la serializzazione delle eccezioni è destinata principalmente al supporto della comunicazione remota, che è stato eliminato in .NET Core 1.0.

    Se il tipo di eccezione personalizzato è definito come quello illustrato nel frammento di codice seguente, è sufficiente rimuovere l'attributo [Serializable], il costruttore di serializzazione e l'override del metodo 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);
        }
    }
    

    In alcuni casi non è possibile rimuovere queste API dal tipo di eccezione personalizzato, ad esempio se si produce una libreria vincolata dai requisiti di compatibilità delle API. In questo caso, è consigliabile rendere obsoleti il costruttore di serializzazione e i metodi GetObjectData usando il codice di diagnostica SYSLIB0051, come illustrato nel codice seguente. Poiché idealmente nessuno all'esterno dell'infrastruttura di serializzazione deve chiamare queste API, l'obsolescenza dovrebbe influire solo su altri tipi che usano come sottoclasse il tipo di eccezione personalizzato. Non dovrebbe influire in modo virale su chiunque effettui acquisizioni, crei costrutti o utilizzi in altro modo il tipo di eccezione personalizzato.

    [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 si esegue la destinazione incrociata per .NET Framework e .NET 8+, è possibile usare un'istruzione #if per applicare in modo condizionale l'obsolescenza. Questa è la stessa strategia usata dal team .NET all'interno della codebase delle librerie .NET per la destinazione incrociata dei runtime.

    [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 è stato dichiarato un tipo che usa come sottoclasse un tipo .NET a cui viene attribuito [Serializable] e vengono visualizzati avvisi SYSLIB0051, seguire le indicazioni per i tipi di eccezione personalizzati nel punto dell'elenco precedente.

Suggerimento

Se il tipo personalizzato [Serializable] non usa come sottoclasse un tipo .NET, non verranno visualizzati avvisi SYSLIB0051. Tuttavia, è consigliabile non annotare il tipo in questo modo, perché le librerie di serializzazione moderne come System.Text.Json non lo richiedono. Provare a rimuovere l'attributo [Serializable] e l'interfaccia ISerializable. Al contrario, fare affidamento sulla libreria di serializzazione per accedere agli oggetti del tipo tramite le relative proprietà pubbliche anziché i relativi campi privati.

Eliminare un avviso

Se è necessario usare le API obsolete, è possibile eliminare l'avviso nel codice o nel file di progetto.

Per eliminare solo una singola violazione, aggiungere direttive del preprocessore al file di origine per disabilitare e quindi riabilitare l'avviso.

// Disable the warning.
#pragma warning disable SYSLIB0051

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

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

Per eliminare tutti gli avvisi SYSLIB0051 nel progetto, aggiungere una proprietà <NoWarn> al file di progetto.

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

Per altre informazioni, vedere Eliminare gli avvisi.

Vedi anche