Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
| Vlastnost | Hodnota |
|---|---|
| ID pravidla | CA1816 |
| Název | Správně použijte GC.SuppressFinalize |
| Kategorie | Využití |
| Oprava, která může být destruktivní nebo nedestruktivní | Nezlomitelný |
| Povoleno ve výchozím nastavení v .NET 10 | Jako návrh |
| Příslušné jazyky | C# a Visual Basic |
Příčina
Porušení tohoto pravidla může být způsobeno:
Metoda v nezapečetěné třídě, která je implementací IDisposable.Dispose a nevolá GC.SuppressFinalize.
Metoda, která není implementací IDisposable.Dispose, ale volá 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 metoda IDisposable.Dispose volána, uvolní prostředky objektu. Díky tomu je finalizace zbytečná. IDisposable.Dispose by mělo volat GC.SuppressFinalize , aby garbage collector nevolal finalizační metodu objektu.
Chcete-li zabránit tomu, aby odvozené typy s finalizátory musely znovu implementovat IDisposable a volat jej, měly by nezapečetěné typy bez finalizátorů stále volat GC.SuppressFinalize.
Jak opravit porušení
Oprava porušení tohoto pravidla:
Pokud je metoda implementací Dispose, přidejte volání na GC.SuppressFinalize.
Pokud metoda není implementací Dispose, buď odeberte volání GC.SuppressFinalize, nebo jej přesuňte do implementace typu Dispose.
Změňte všechna volání GC.SuppressFinalize tak, aby předávala this (C#) nebo Me (Visual Basic).
Pokud typ není určen k přepsání, označte ho jako
sealed.
Kdy potlačit upozornění
Potlačte upozornění z tohoto pravidla pouze tehdy, pokud 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 této situaci vede neúspěšné potlačení finalizace ke snížení výkonu 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á this (C#) ani Me (Visual Basic). V důsledku toho tento kód porušuje pravidlo 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;
}
}
}
Příklad, který splňuje CA1816
Tento příklad ukazuje metodu, která správně volá GC.SuppressFinalize předáním tento objekt (C#) nebo 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;
}
}
}
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