Chiamare correttamente GC.SuppressFinalize
Aggiornamento: novembre 2007
TypeName |
CallGCSuppressFinalizeCorrectly |
CheckId |
CA1816 |
Category |
Microsoft. Utilizzo |
Breaking Change |
Non sostanziale |
Causa
Un metodo che rappresenta un'implementazione di Dispose non chiama GC.SuppressFinalize.
-oppure-
Un metodo che non rappresenta un'implementazione di Dispose chiama GC.SuppressFinalize.
-oppure-
Un metodo chiama GC.SuppressFinalize e passa un elemento diverso da this (Me in Visual Basic).
Descrizione della regola
Il metodo 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 Dispose, le risorse dell'oggetto vengono liberate. In questo modo, la finalizzazione non è più necessaria. 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.
Correzione di 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.
Modificare tutte le chiamate a GC.SuppressFinalize per passare 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 erroneamente GC.SuppressFinalize passandolo true (True in Visual Basic).
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
I tipi eliminabili devono dichiarare un finalizzatore
Vedere anche
Riferimenti
Implementazione dei metodi Finalize e Dispose per la pulitura delle risorse non gestite