Aracılığıyla paylaş


CA1816: GC.SuppressFinalize öğesini doğru çağırın

Özellik Değer
Kural Kimliği CA1816
Başlık GC.SuppressFinalize'ı doğru çağırın
Kategori Kullanım
Hataya neden olan veya bozulmayan düzeltme Hataya neden olmayan
.NET 9'da varsayılan olarak etkin Öneri olarak

Neden

Bu kuralın ihlalleri aşağıdakilerden kaynaklanabilir:

Kural açıklaması

IDisposable.Dispose yöntemi, kullanıcıların nesne çöp toplama için kullanılabilir duruma gelmeden önce istedikleri zaman kaynakları serbest bırakmasına olanak tanır. IDisposable.Dispose yöntemi çağrılırsa, nesnesinin kaynaklarını serbesttir. Bu, sonlandırmayı gereksiz kılar. IDisposable.Dispose atık toplayıcının nesnenin sonlandırıcısını çağırmaması için çağırmalıdır GC.SuppressFinalize .

Sonlandırıcıları olan türetilmiş türlerin yeniden IDisposable tahmin etmek ve çağırmak zorunda olmasını önlemek için, sonlandırıcıları olmayan korumasız türler yine çağırmalıdır GC.SuppressFinalize.

İhlalleri düzeltme

Bu kuralın ihlalini düzeltmek için:

Uyarıların ne zaman bastırılması gerekiyor?

Bu kuraldan gelen bir uyarıyı, diğer nesnelerin kullanım ömrünü denetlemek için bilerek kullanıyorsanız GC.SuppressFinalize gizleyebilirsiniz. uygulaması çağrısı GC.SuppressFinalizeyapmıyorsa, bu kuraldan gelen bir uyarıyı Dispose gizlemeyin. Bu durumda, sonlandırmanın gizlenmemesi performansı düşürür ve hiçbir avantaj sağlamaz.

Uyarıyı gizleme

Yalnızca tek bir ihlali engellemek istiyorsanız, kuralı devre dışı bırakmak ve sonra yeniden etkinleştirmek için kaynak dosyanıza ön işlemci yönergeleri ekleyin.

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

Bir dosya, klasör veya projenin kuralını devre dışı bırakmak için, yapılandırma dosyasındaki önem derecesini none olarak ayarlayın.

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

Daha fazla bilgi için bkz . Kod analizi uyarılarını gizleme.

CA1816'ya aykırı örnek

Bu kod, öğesini çağıran GC.SuppressFinalizeancak bu (C#) veya Ben (Visual Basic) geçirmeyen bir yöntemi gösterir. Sonuç olarak, bu kod CA1816 kuralını ihlal eder.

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

CA1816'ya uyduğunu gösteren örnek

Bu örnekte, bu (C#) veya Ben (Visual Basic) geçirerek doğru şekilde çağıran GC.SuppressFinalize bir yöntem gösterilmektedir.

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

Ayrıca bkz.