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
Düzeltme bozucu ya da bozmayan olabilir Kesintisiz
.NET 10'da varsayılan olarak etkin Öneri olarak
Geçerli diller C# ve Visual Basic

Neden

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

Kural açıklaması

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

Sonlandırıcıları olan türetilmiş türlerin IDisposable'i yeniden uygulamak ve çağırmak zorunda kalmasını önlemek için, sonlandırıcıları olmayan mühürlenmemiş türler yine de GC.SuppressFinalize'i çağırmalıdır.

İhlalleri düzeltme

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

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

Diğer nesnelerin kullanım ömrünü denetlemek için GC.SuppressFinalize bilinçli bir şekilde kullanıyorsanız, bu kuraldan gelen bir uyarıyı yalnızca o zaman bastırabilirsiniz. Dispose GC.SuppressFinalize çağrısı yapmıyorsa, bu kuraldan gelen bir uyarıyı gizlemeyin. Bu durumda, sonlandırmanın bastırılmaması performansı düşürür ancak 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 noneolarak 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, GC.SuppressFinalize öğesini çağıran, ancak this (C#) veya Me (Visual Basic) geçirmeyen bir yöntemi gösterir. Sonuç olarak, bu kod CA1816 kuralını ihlal eder.

Public Class MyStreamClass
    Implements IDisposable

    Private _stream As New MemoryStream

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        ' Violates rule.
        GC.SuppressFinalize(True)
    End Sub

    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If _stream IsNot Nothing Then
                _stream.Dispose()
                _stream = Nothing
            End If
        End If
    End Sub

End Class
public class MyStreamClass : IDisposable
{
    private MemoryStream? _stream = new();

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(true);  // Violates rule
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            _stream?.Dispose();
            _stream = null;
        }
    }
}

CA1816'ya uyduğunu gösteren örnek

Bu örnek, GC.SuppressFinalize'ü doğru bir şekilde çağıran, this (C#) veya Me (Visual Basic) argümanlarını geçiren bir yöntemi göstermektedir.

Public Class MyStreamClass
    Implements IDisposable

    Private _stream As New MemoryStream

    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 _stream IsNot Nothing Then
                _stream.Dispose()
                _stream = Nothing
            End If
        End If
    End Sub

End Class
public class MyStreamClass : IDisposable
{
    private MemoryStream? _stream = new();

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            _stream?.Dispose();
            _stream = null;
        }
    }
}

Ayrıca bkz.