CA1816: Wywołaj poprawnie GC.SuppressFinalize
Właściwości | Wartość |
---|---|
Identyfikator reguły | CA1816 |
Tytuł | Poprawnie wywołaj metodę GC.SuppressFinalize |
Kategoria | Użycie |
Poprawka powodująca niezgodność lub niezgodność | Niezgodność |
Domyślnie włączone na platformie .NET 9 | Jako sugestia |
Przyczyna
Naruszenia tej reguły mogą być spowodowane przez:
W niezaznaczonej klasie metoda, która jest implementacją IDisposable.Dispose metody i nie wywołuje metody GC.SuppressFinalize.
Metoda, która nie jest implementacją IDisposable.Dispose metody i wywołuje metodę GC.SuppressFinalize.
Metoda, która wywołuje GC.SuppressFinalize i przekazuje coś innego niż ten (C#) lub Me (Visual Basic).
Opis reguły
Metoda IDisposable.Dispose umożliwia użytkownikom wydawanie zasobów w dowolnym momencie, zanim obiekt stanie się dostępny do odzyskiwania pamięci. IDisposable.Dispose Jeśli metoda jest wywoływana, zwalnia zasoby obiektu. To sprawia, że finalizacja jest niepotrzebna. IDisposable.Dispose należy wywołać GC.SuppressFinalize metodę , aby moduł odśmieceń pamięci nie wywołuje finalizatora obiektu.
Aby zapobiec konieczności ponownego implementowania IDisposable typów pochodnych z finalizatorami i wywołania ich, nierozpoznane typy bez finalizatorów powinny nadal wywoływać metodę GC.SuppressFinalize.
Jak naprawić naruszenia
Aby naprawić naruszenie tej reguły:
Jeśli metoda jest implementacją Disposemetody , dodaj wywołanie do GC.SuppressFinalizemetody .
Jeśli metoda nie jest implementacją Disposemetody , usuń wywołanie GC.SuppressFinalize metody lub przenieś ją do implementacji Dispose typu.
Zmień wszystkie wywołania, aby przekazać GC.SuppressFinalize to (C#) lub Me (Visual Basic).
Jeśli typ nie ma zostać zastąpiony, oznacz go jako
sealed
.
Kiedy pomijać ostrzeżenia
Pomijanie ostrzeżenia z tej reguły tylko wtedy, gdy celowo używasz GC.SuppressFinalize do kontrolowania okresu istnienia innych obiektów. Nie pomijaj ostrzeżenia z tej reguły, jeśli implementacja Dispose elementu nie wywołuje metody GC.SuppressFinalize. W takiej sytuacji nie można pominąć finalizacji obniża wydajność i nie zapewnia żadnych korzyści.
Pomijanie ostrzeżenia
Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.
#pragma warning disable CA1816
// The code that's violating the rule is on this line.
#pragma warning restore CA1816
Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none
w pliku konfiguracji.
[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none
Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.
Przykład naruszający ca1816
Ten kod przedstawia metodę, która wywołuje GC.SuppressFinalizemetodę , ale nie przekazuje tej metody (C#) ani Me (Visual Basic). W związku z tym ten kod narusza regułę 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;
}
}
}
}
Przykład spełniający wymagania ca1816
W tym przykładzie pokazano metodę, która poprawnie wywołuje GC.SuppressFinalize tę metodę (C#) lub 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;
}
}
}
}
Powiązane reguły
- CA2215: Metody Dispose powinny wywoływać metodę Dispose klasy podstawowej
- CA2216: Typy możliwe do likwidacji powinny deklarować finalizator