CA1816: Volejte správně GC.SuppressFinalize
Vlastnost | Hodnota |
---|---|
ID pravidla | CA1816 |
Název | Volejte správně GC.SuppressFinalize |
Kategorie | Využití |
Oprava způsobující chybu nebo chybu způsobující chybu | Nenarušující |
Povoleno ve výchozím nastavení v .NET 9 | Jako návrh |
Příčina
Porušení tohoto pravidla může být způsobeno:
V nezapečetěné třídě metoda, která je implementací IDisposable.Dispose a nevolá GC.SuppressFinalize.
Metoda, která není implementací IDisposable.Dispose a volání GC.SuppressFinalize.
Metoda, která volá GC.SuppressFinalize a předává něco jiného než tento (C#) nebo Já (Visual Basic).
Popis pravidla
Metoda IDisposable.Dispose umožňuje uživatelům uvolnit prostředky kdykoli předtím, než bude objekt k dispozici pro uvolňování paměti. Pokud je IDisposable.Dispose volána metoda, uvolní prostředky objektu. Díky tomu je finalizace zbytečná. IDisposable.Dispose by mělo volat GC.SuppressFinalize , aby systém uvolňování paměti nevolal finalizační metodu objektu.
Chcete-li zabránit odvozeným typům s finalizátory v reimplementu IDisposable a volat jej, nezapečetěné typy bez finalizátorů by měly stále volat GC.SuppressFinalize.
Jak opravit porušení
Oprava porušení tohoto pravidla:
Pokud je metoda implementace Dispose, přidejte volání GC.SuppressFinalize.
Pokud metoda není implementace Dispose, buď odebrat volání GC.SuppressFinalize nebo přesunout do implementace typu Dispose .
Změňte všechna volání tak, aby GC.SuppressFinalize předala toto volání (C#) nebo Já (Visual Basic).
Pokud typ není určen k přepsání, označte ho jako
sealed
.
Kdy potlačit upozornění
Potlačit upozornění z tohoto pravidla pouze v případě, že záměrně používáte GC.SuppressFinalize k řízení životnosti jiných objektů. Nepotlačujte upozornění z tohoto pravidla, pokud implementace Dispose nevolá GC.SuppressFinalize. V takové situaci se nedaří potlačit snížení výkonu finalizace a neposkytuje žádné výhody.
Potlačení upozornění
Pokud chcete pouze potlačit jedno porušení, přidejte do zdrojového souboru direktivy preprocesoru, abyste pravidlo zakázali a znovu povolili.
#pragma warning disable CA1816
// The code that's violating the rule is on this line.
#pragma warning restore CA1816
Pokud chcete pravidlo pro soubor, složku nebo projekt zakázat, nastavte jeho závažnost v none
konfiguračním souboru.
[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none
Další informace naleznete v tématu Jak potlačit upozornění analýzy kódu.
Příklad, který porušuje CA1816
Tento kód ukazuje metodu, která volá GC.SuppressFinalize, ale nepředává tuto metodu (C#) nebo Me (Visual Basic). V důsledku toho tento kód porušuje pravidlo 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;
}
}
}
}
Příklad, který splňuje CA1816
Tento příklad ukazuje metodu, která správně volá GC.SuppressFinalize předáním této metody (C#) nebo 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;
}
}
}
}
Související pravidla
- CA2215: Metody Dispose by měly volat uvolnění třídy Base
- CA2216: Uvolnitelné typy by měly deklarovat finalizační metodu