CA1816: GC.SuppressFinalize korrekt aufrufen.
Eigenschaft | Wert |
---|---|
Regel-ID | CA1816 |
Titel | GC.SuppressFinalize korrekt aufrufen. |
Kategorie | Verwendung |
Fix führt oder führt nicht zur Unterbrechung | Nicht unterbrechend |
Standardmäßig in .NET 8 aktiviert | Als Vorschlag |
Ursache
Verstöße gegen diese Regel können folgende Ursachen haben:
In einer nicht versiegelten Klasse, eine Methode, die eine Implementierung von IDisposable.Dispose ist und GC.SuppressFinalize nicht aufruft.
Eine Methode, die keine Implementierung von IDisposable.Dispose ist und GC.SuppressFinalize aufruft.
Eine Methode, die GC.SuppressFinalize aufruft und and etwas anderes als diese (C#) oder Me (Visual Basic) übergibt.
Regelbeschreibung
Mit der IDisposable.Dispose-Methode können Benutzer jederzeit Ressourcen freigeben, bevor das Objekt für Garbage Collection verfügbar wird. Wenn die IDisposable.Dispose-Methode aufgerufen wird, gibt Sie Ressourcen des Objekts frei. Dies macht die Finalisierung unnötig. IDisposable.Dispose sollte GC.SuppressFinalize aufrufen, damit der Garbage Collector den Finalizer des Objekts nicht aufruft.
Um zu verhindern, dass abgeleitete Typen mit Finalizern IDisposable neu implementieren und es aufrufen müssen, sollten unversiegelte Typen ohne Finalizer trotzdem GC.SuppressFinalize aufrufen.
Behandeln von Verstößen
Um einen Verstoß gegen diese Regel zu beheben:
Wenn die Methode eine Implementierung von Dispose ist, fügen Sie einen Aufruf von GC.SuppressFinalize hinzu.
Wenn es sich bei der Methode nicht um eine Implementierung von Disposehandelt, entfernen Sie entweder den Aufruf von GC.SuppressFinalize oder verschieben Sie es in die Implementierung von Dispose des Typs .
Ändern Sie alle Aufrufe von GC.SuppressFinalize, um diese (C#) oder Me (Visual Basic) zu übergeben.
Wenn der Typ nicht überschrieben werden soll, markieren Sie ihn als
sealed
.
Wann sollten Warnungen unterdrückt werden?
Unterdrücken Sie eine Warnung aus dieser Regel nur, wenn Sie GC.SuppressFinalize absichtlich verwenden, um die Lebensdauer anderer Objekte zu steuern. Unterdrücken Sie keine Warnung aus dieser Regel, wenn eine Implementierung von Dispose nicht GC.SuppressFinalize aufruft. In dieser Situation wird die Leistung durch einen Fehler beim Unterdrücken der Finalisierung beeinträchtigt und bietet keine Vorteile.
Unterdrücken einer Warnung
Um nur eine einzelne Verletzung zu unterdrücken, fügen Sie der Quelldatei Präprozessoranweisungen hinzu, um die Regel zu deaktivieren und dann wieder zu aktivieren.
#pragma warning disable CA1816
// The code that's violating the rule is on this line.
#pragma warning restore CA1816
Um die Regel für eine Datei, einen Ordner oder ein Projekt zu deaktivieren, legen Sie den Schweregrad in der Konfigurationsdatei auf none
fest.
[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none
Weitere Informationen finden Sie unter Vorgehensweise: Unterdrücken von Codeanalyse-Warnungen.
Beispiel, das gegen CA1816 verstößt
Dieser Code zeigt eine Methode an, die GC.SuppressFinalize aufruft, aber nicht diese (C#) oder Me (Visual Basic) übergibt. Dies führt dazu, dass dieser Code gegen die Regel CA1816 verstößt.
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;
}
}
}
}
Beispiel, bei dem CA1816 erfüllt wird
Dieses Beispiel zeigt eine Methode, die GC.SuppressFinalize korrekt aufruft, indem diese (C#) oder Me (Visual Basic)übergeben wird.
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;
}
}
}
}
Ähnliche Regeln
- CA2215: Dispose-Methoden müssen die Dispose-Funktion der Basisklasse aufrufen.
- CA2216: Verwerfbare Typen sollten einen Finalizer deklarieren.