Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de changer d’annuaire.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer d’annuaire.
| Propriété | Value |
|---|---|
| Identificateur de la règle | CA1816 |
| Titre | Appeler GC.SuppressFinalize correctement |
| Catégorie | Utilisation |
| Le correctif est cassant ou non cassant | Sans rupture |
| Activé par défaut dans .NET 10 | À titre de suggestion |
Cause
Les violations de cette règle peuvent être provoquées par :
Dans une classe non scellée, une méthode qui est une implémentation de IDisposable.Dispose et n’appelle pas GC.SuppressFinalize.
Une méthode qui n’est pas une implémentation de IDisposable.Dispose et appelle GC.SuppressFinalize.
Une méthode qui appelle GC.SuppressFinalize et transmet quelque chose d’autre que this (C#) ou Me (Visual Basic).
Description de la règle
La méthode IDisposable.Dispose permet aux utilisateurs de libérer des ressources avant que l'objet ne soit disponible pour le ramasse-miettes. 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 afin que le garbage collector n’appelle pas le finaliseur de l’objet.
Pour empêcher les types dérivés avec des finaliseurs d’avoir à réapprouver IDisposable et de l’appeler, les types non scellés sans finaliseurs doivent toujours appeler GC.SuppressFinalize.
Comment corriger les violations
Pour corriger toute 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.
Remplacez tous les appels à GC.SuppressFinalize pour passer this (C#) ou Me (Visual Basic).
Si le type n’est pas destiné à être remplacé, marquez-le comme
sealed.
Quand supprimer les avertissements
Supprimez uniquement un avertissement de cette règle si vous utilisez GC.SuppressFinalize délibérément pour contrôler la durée de vie d’autres objets. Ne supprimez pas d’avertissement de cette règle si une implémentation de Dispose n’appelle pas GC.SuppressFinalize. Dans ce cas, l’échec de la suppression de la finalisation dégrade les performances et n’offre aucun avantage.
Supprimer un avertissement
Si vous voulez supprimer une seule violation, ajoutez des directives de préprocesseur à votre fichier source pour désactiver et réactiver la règle.
#pragma warning disable CA1816
// The code that's violating the rule is on this line.
#pragma warning restore CA1816
Pour désactiver la règle sur un fichier, un dossier ou un projet, définissez sa gravité sur none dans le fichier de configuration.
[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none
Pour plus d’informations, consultez Comment supprimer les avertissements de l’analyse de code.
Exemple qui enfreint la règle CA1816
Ce code montre une méthode qui appelle GC.SuppressFinalize, mais ne passe pas this (C#) ou Me (Visual Basic). Par conséquent, ce code enfreint la règle CA1816.
Public Class MyStreamClass
Implements IDisposable
Private _stream As New MemoryStream
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
' Violates rule.
GC.SuppressFinalize(True)
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If _stream IsNot Nothing Then
_stream.Dispose()
_stream = Nothing
End If
End If
End Sub
End Class
public class MyStreamClass : IDisposable
{
private MemoryStream? _stream = new();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(true); // Violates rule
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_stream?.Dispose();
_stream = null;
}
}
}
Exemple qui satisfait à CA1816
Cet exemple montre une méthode qui appelle GC.SuppressFinalize correctement en passant this (C#) ou Me (Visual Basic).
Public Class MyStreamClass
Implements IDisposable
Private _stream As New MemoryStream
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 _stream IsNot Nothing Then
_stream.Dispose()
_stream = Nothing
End If
End If
End Sub
End Class
public class MyStreamClass : IDisposable
{
private MemoryStream? _stream = new();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_stream?.Dispose();
_stream = null;
}
}
}
Règles associées
- CA2215 : Les méthodes Dispose doivent appeler la méthode Dispose de la classe de base
- CA2216 : Les types pouvant être supprimés doivent déclarer un finaliseur