CA1816: Chiamare GC.SuppressFinalize correttamente
TypeName |
CallGCSuppressFinalizeCorrectly |
CheckId |
CA1816 |
Category |
Microsoft. Utilizzo |
Breaking Change |
Non sostanziale |
Causa
Un metodo che rappresenta un'implementazione di IDisposable.Dispose non chiama GC.SuppressFinalize.
Un metodo che non rappresenta un'implementazione di IDisposable.Dispose chiama GC.SuppressFinalize.
Un metodo chiama GC.SuppressFinalize passando un argomento diverso da questo (Me in Visual Basic).
Descrizione della regola
Il metodo IDisposable.Dispose consente agli utenti di rilasciare risorse in qualsiasi momento prima che l'oggetto diventi disponibile per un'operazione di Garbage Collection. Se viene chiamato il metodo IDisposable.Dispose, le risorse dell'oggetto vengono liberate. In questo modo non è necessario effettuare la finalizzazione. IDisposable.Dispose dovrebbe chiamare GC.SuppressFinalize affinché il finalizzatore dell'oggetto non venga chiamato dal Garbage Collector.
Per evitare che tipi derivati con finalizzatori debbano implementare nuovamente [System.IDisposable] e chiamarlo, è ancora necessario che i tipi non sealed senza finalizzatori chiamino 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 oppure spostarla nell'implementazione di Dispose del tipo.
Modifica tutte le chiamate in GC.SuppressFinalize per passare l'elemento this (Me in Visual Basic).
Esclusione di avvisi
Escludere un avviso da questa regola solo se si utilizza deliberatamente GC.SuppressFinalize per controllare la durata di altri oggetti. Non escludere un avviso da questa regola se un'implementazione di Dispose non chiama GC.SuppressFinalize. In questa situazione, la mancata esclusione della finalizzazione comporta un calo delle prestazioni e non offre alcun vantaggio.
Esempio
Nell'esempio riportato di seguito viene illustrato un metodo che chiama GC.SuppressFinalize in modo non corretto.
Imports System
Imports System.Data.SqlClient
Namespace Samples
Public Class DatabaseConnector
Implements IDisposable
Private _Connection As New SqlConnection
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(True) ' Violates rules
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
End Namespace
using System;
using System.Data.SqlClient;
namespace Samples
{
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;
}
}
}
}
}
Nell'esempio riportato di seguito viene illustrato un metodo che chiama correttamente GC.SuppressFinalize.
Imports System
Imports System.Data.SqlClient
Namespace Samples
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
End Namespace
using System;
using System.Data.SqlClient;
namespace Samples
{
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
Vedere anche
Riferimenti
Implementazione dei metodi Finalize e Dispose per la pulizia delle risorse non gestite