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 9 | Som förslag |
Orsak
Överträdelser av den här regeln kan orsakas av:
I en oförseglade klass anropar GC.SuppressFinalizeen metod som är en implementering av IDisposable.Dispose och inte .
En metod som inte är en implementering av IDisposable.Dispose och anropar GC.SuppressFinalize.
En metod som anropar GC.SuppressFinalize och skickar något annat än detta (C#) eller Mig (Visual Basic).
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:
Om metoden är en implementering av Disposelägger du till ett anrop till GC.SuppressFinalize.
Om metoden inte är en implementering av Disposetar du antingen bort anropet till GC.SuppressFinalize eller flyttar det till typens Dispose implementering.
Ändra alla anrop till GC.SuppressFinalize för att skicka detta (C#) eller Mig (Visual Basic).
Om typen inte är avsedd att åsidosättas markerar du den som
sealed
.
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;
}
}
}
}
Relaterade regler
- CA2215: Kassera metoder ska anropa basklassens bortskaffning
- CA2216: Engångstyper bör deklarera finalator