Share via


CA1816: Ring GC. SuppressFinalize korrekt

Property Värde
Regel-ID CA1816
Title Anropa GC. SuppressFinalize korrekt
Kategori Användning
Korrigeringen är icke-bakåtkompatibel Icke-icke-bryta
Aktiverad som standard i .NET 8 Som förslag

Orsak

Överträdelser av den här regeln kan orsakas av:

Regelbeskrivning

Med IDisposable.Dispose metoden kan användarna frigöra resurser när som helst innan objektet blir tillgängligt för skräpinsamling. IDisposable.Dispose Om metoden anropas frigör den resurser för objektet. Detta gör slutförande onödigt. IDisposable.Dispose ska anropa GC.SuppressFinalize så att skräpinsamlaren inte anropar objektets slutpunkt.

För att förhindra härledda typer med finalizers från att behöva omimplementeras IDisposable och anropa det, bör oförseglade typer utan finalizers fortfarande anropa GC.SuppressFinalize.

Så här åtgärdar du överträdelser

Så här åtgärdar du ett brott mot den här regeln:

När du ska ignorera varningar

Utelämna bara en varning från den här regeln om du avsiktligt använder GC.SuppressFinalize för att styra livslängden för andra objekt. Ignorera inte en varning från den här regeln om en implementering av Dispose inte anropar GC.SuppressFinalize. I den här situationen försämras prestanda och inga fördelar om du inte undertrycker slutförande.

Ignorera en varning

Om du bara vill förhindra en enda överträdelse lägger du till förprocessordirektiv i källfilen för att inaktivera och aktiverar sedan regeln igen.

#pragma warning disable CA1816
// The code that's violating the rule is on this line.
#pragma warning restore CA1816

Om du vill inaktivera regeln för en fil, mapp eller ett projekt anger du dess allvarlighetsgrad till none i konfigurationsfilen.

[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none

Mer information finns i Så här utelämnar du kodanalysvarningar.

Exempel som bryter mot CA1816

Den här koden visar en metod som anropar GC.SuppressFinalize, men inte skickar detta (C#) eller Mig (Visual Basic). Därför bryter den här koden mot regeln 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;
            }
        }
    }
}

Exempel som uppfyller CA1816

Det här exemplet visar en metod som anropar GC.SuppressFinalize korrekt genom att skicka detta (C#) eller Mig (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;
            }
        }
    }
}

Se även