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:
Korumasız bir sınıfta uygulaması olan ve çağırmayan GC.SuppressFinalizebir IDisposable.Dispose yöntemdir.
uygulaması olmayan ve çağıran GC.SuppressFinalizebir IDisposable.Dispose yöntem.
Bu (C#) veya Ben (Visual Basic) dışında bir şeyi çağıran GC.SuppressFinalize ve geçiren bir yöntem.
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:
yöntemi uygulamasıysa Disposeöğesine bir çağrı GC.SuppressFinalizeekleyin.
yöntemi uygulaması Disposedeğilse, çağrısı GC.SuppressFinalize kaldırın veya türün Dispose uygulamasına taşıyın.
Bunu (C#) veya Ben'i (Visual Basic) geçirmek için GC.SuppressFinalize tüm çağrıları olarak değiştirin.
Türün geçersiz kılınması amaçlanmamışsa olarak işaretleyin
sealed
.
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;
}
}
}
}
İlgili kurallar
- CA2215: Atma yöntemleri taban sınıf atmayı çağırmalıdır
- CA2216: Atılabilir türler sonlandırıcıyı bildirmelidir