Teilen über


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:

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:

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;
            }
        }
    }
}

Siehe auch