CA1816 : Appeler GC.SuppressFinalize correctement
TypeName |
CallGCSuppressFinalizeCorrectly |
CheckId |
CA1816 |
Catégorie |
Microsoft.Utilisation |
Modification avec rupture |
Modification sans rupture |
Cause
Une méthode qui est une implémentation de IDisposable.Dispose n'appelle pas GC.SuppressFinalize.
Une méthode qui n'est pas une implémentation de IDisposable.Dispose appelle GC.SuppressFinalize.
Une méthode appelle GC.SuppressFinalize et passe une valeur différente de this (Me en Visual Basic).
Description de la règle
La méthode IDisposable.Dispose permet aux utilisateurs de libérer des ressources n'importe quand avant que l'objet devienne disponible pour l'opération garbage collection.Si la méthode IDisposable.Dispose est appelée, elle libère les ressources de l'objet.Cela rend la finalisation inutile.IDisposable.Dispose doit appeler GC.SuppressFinalize ainsi le garbage collector n'appelle pas le finaliseur de l'objet.
Pour éviter que les types dérivés avec finaliseurs ne doivent réimplémenter [System.IDisposable] et l'appeler, des types unsealed sans finaliseur doivent toujours appeler GC.SuppressFinalize.
Comment corriger les violations
Pour corriger une violation de cette règle :
Si la méthode est une implémentation de Dispose, ajoutez un appel à GC.SuppressFinalize.
Si la méthode n'est pas une implémentation de Dispose, supprimez l'appel à GC.SuppressFinalize ou déplacez-le vers l'implémentation Dispose du type.
Modifiez tous les appels enGC.SuppressFinalize pour passer ceci (Moi en Visual Basic).
Quand supprimer les avertissements
Supprimez uniquement un avertissement de cette règle si vous utilisez délibérément GC.SuppressFinalize pour contrôler la durée de vie des autres objets.Ne supprimez pas un avertissement de cette règle si une implémentation de Dispose n'appelle pas GC.SuppressFinalize.Dans cette situation, ne pas parvenir à supprimer une finalisation fait baisser les performances et n'apporte aucun avantage.
Exemple
L'exemple suivant montre une méthode qui appelle GC.SuppressFinalize de manière incorrecte.
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;
}
}
}
}
}
L'exemple suivant montre une méthode qui appelle GC.SuppressFinalize de manière correcte.
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;
}
}
}
}
}
Règles connexes
CA2215 : Les méthodes Dispose doivent appeler la fonction Dispose de la classe de base
CA2216 : Les types pouvant être supprimés doivent déclarer un finaliseur