CA1816: Chiamare GC.SuppressFinalize correttamente
Proprietà | valore |
---|---|
ID regola | CA1816 |
Title | Chiamare GC.SuppressFinalize correttamente |
Categoria | Utilizzo |
Correzione che causa un'interruzione o un'interruzione | Nessuna interruzione |
Abilitato per impostazione predefinita in .NET 8 | Come suggerimento |
Causa
Le violazioni di questa regola possono essere causate da:
In una classe non bloccato, un metodo che rappresenta un'implementazione di IDisposable.Dispose e non chiama GC.SuppressFinalize.
Un metodo che non è un'implementazione di IDisposable.Dispose e chiama GC.SuppressFinalize.
Metodo che chiama GC.SuppressFinalize e passa qualcosa di diverso da questo (C#) o Me (Visual Basic).
Descrizione regola
Il IDisposable.Dispose metodo consente agli utenti di rilasciare le risorse in qualsiasi momento prima che l'oggetto diventi disponibile per l'operazione di Garbage Collection. Se viene chiamato il IDisposable.Dispose metodo , libera le risorse dell'oggetto . In questo modo, la finalizzazione non è necessaria. IDisposable.Dispose deve chiamare GC.SuppressFinalize in modo che il Garbage Collector non chiami il finalizzatore dell'oggetto.
Per evitare che i tipi derivati con finalizzatori debbano ripetere IDisposable e chiamarlo, i tipi non bloccati senza finalizzatori devono comunque chiamare GC.SuppressFinalize.
Come correggere le violazioni
Per correggere una violazione di questa regola:
Se il metodo è un'implementazione di Dispose, aggiungere una chiamata a GC.SuppressFinalize.
Se il metodo non è un'implementazione di Dispose, rimuovere la chiamata a GC.SuppressFinalize o spostarla nell'implementazione del Dispose tipo.
Modificare tutte le chiamate a per passare questo (C#) o Me (Visual Basic).Change all calls to GC.SuppressFinalize to pass this (C#) or Me (Visual Basic).
Se il tipo non deve essere sottoposto a override, contrassegnarlo come
sealed
.
Quando eliminare gli avvisi
Eliminare un avviso da questa regola solo se si usa GC.SuppressFinalize deliberatamente per controllare la durata di altri oggetti. Non eliminare un avviso da questa regola se un'implementazione di Dispose non chiama GC.SuppressFinalize. In questa situazione, la mancata eliminazione della finalizzazione degrada le prestazioni e non offre alcun vantaggio.
Eliminare un avviso
Se si vuole eliminare una singola violazione, aggiungere direttive del preprocessore al file di origine per disabilitare e quindi riabilitare la regola.
#pragma warning disable CA1816
// The code that's violating the rule is on this line.
#pragma warning restore CA1816
Per disabilitare la regola per un file, una cartella o un progetto, impostarne la gravità none
su nel file di configurazione.
[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none
Per altre informazioni, vedere Come eliminare gli avvisi di analisi del codice.
Esempio che viola CA1816
Questo codice mostra un metodo che chiama , ma non passa questo (C#) o Me (Visual Basic).This code shows a method that calls GC.SuppressFinalize, but't pass this (C#) or Me (Visual Basic). Di conseguenza, questo codice viola la regola CA1816.
Public Class DatabaseConnector
Implements IDisposable
Private _Connection As New SqlConnection
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
' Violates rules
GC.SuppressFinalize(True)
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If _Connection IsNot Nothing Then
_Connection.Dispose()
_Connection = Nothing
End If
End If
End Sub
End Class
public class DatabaseConnector : IDisposable
{
private SqlConnection? _Connection = new SqlConnection();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(true); // Violates rule
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_Connection != null)
{
_Connection.Dispose();
_Connection = null;
}
}
}
}
Esempio che soddisfa CA1816
In questo esempio viene illustrato un metodo che chiama correttamente passando questo (C#) o Me (Visual Basic).This example shows a method that correctly calls GC.SuppressFinalize by passing this (C#) or Me (Visual Basic).
Public Class DatabaseConnector
Implements IDisposable
Private _Connection As New SqlConnection
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If _Connection IsNot Nothing Then
_Connection.Dispose()
_Connection = Nothing
End If
End If
End Sub
End Class
public class DatabaseConnector : IDisposable
{
private SqlConnection? _Connection = new SqlConnection();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_Connection != null)
{
_Connection.Dispose();
_Connection = null;
}
}
}
}
Regole correlate
- CA2215: I metodi Dispose devono chiamare il metodo Dispose della classe base
- CA2216: I tipi Disposable devono dichiarare un finalizzatore