Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
| Eigenschap | Waarde |
|---|---|
| Regel-id | CA1816 |
| Titel | Roep GC.SuppressFinalize correct aan |
| Categorie | Gebruik |
| Fix kan brekend of niet-brekend zijn | Niet-brekend |
| Standaard ingeschakeld in .NET 10 | Als suggestie |
| Toepasselijke talen | C# en Visual Basic |
Oorzaak
Schendingen van deze regel kunnen worden veroorzaakt door:
In een niet-verzegelde klasse is er een methode die een implementatie is van IDisposable.Dispose, maar die niet GC.SuppressFinalize aanroept.
Een methode die geen implementatie is van IDisposable.Dispose en aanroept GC.SuppressFinalize.
Een methode die GC.SuppressFinalize aanroept en iets anders dan this (C#) of Me (Visual Basic) doorgeeft.
Beschrijving van regel
Met de IDisposable.Dispose methode kunnen gebruikers op elk gewenst moment resources vrijgeven voordat het object beschikbaar komt voor garbagecollection. Als de IDisposable.Dispose methode wordt aangeroepen, worden resources van het object vrijgemaakt. Dit maakt het voltooien onnodig. IDisposable.Dispose zou GC.SuppressFinalize moeten aanroepen zodat de garbage-collector de finalizer van het object niet aanroept.
Om te voorkomen dat afgeleide typen met finalizers IDisposable opnieuw moeten implementeren en aanroepen, zouden niet-verzegelde typen zonder finalizers nog steeds GC.SuppressFinalize moeten aanroepen.
Hoe schendingen op te lossen
Een schending van deze regel oplossen:
Als de methode een implementatie is van Dispose, voegt u een aanroep toe aan GC.SuppressFinalize.
Als de methode geen implementatie van Dispose is, verwijdert u de aanroep naar GC.SuppressFinalize of verplaatst u deze naar de implementatie van het type's Dispose.
Wijzig alle aanroepen naar GC.SuppressFinalize om deze (C#) of Me (Visual Basic) door te geven.
Als het type niet is bedoeld om te worden overschreven, markeert u het als
sealed.
Wanneer waarschuwingen onderdrukken
Onderdruk alleen een waarschuwing van deze regel als u bewust GC.SuppressFinalize gebruikt om de levensduur van andere objecten te controleren. Onderdruk geen waarschuwing van deze regel als een implementatie van Dispose niet GC.SuppressFinalize aanroept. In deze situatie vermindert het de prestaties om voltooien te onderdrukken en biedt dit geen voordelen.
Een waarschuwing onderdrukken
Als u slechts één schending wilt onderdrukken, voegt u preprocessorrichtlijnen toe aan uw bronbestand om de regel uit te schakelen en vervolgens opnieuw in te schakelen.
#pragma warning disable CA1816
// The code that's violating the rule is on this line.
#pragma warning restore CA1816
Als u de regel voor een bestand, map of project wilt uitschakelen, stelt u de ernst none ervan in op het configuratiebestand.
[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none
Zie voor meer informatie Hoe codeanalysewaarschuwingen te onderdrukken.
Voorbeeld dat CA1816 schendt
Deze code toont een methode die GC.SuppressFinalize aanroept, maar this (C#) of Me (Visual Basic) niet doorgeeft. Als gevolg hiervan schendt deze code regel CA1816.
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;
}
}
}
Voorbeeld dat voldoet aan CA1816
In dit voorbeeld wordt een methode getoond die correct GC.SuppressFinalize aanroept door dit (C#) of Me (Visual Basic) door te geven.
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;
}
}
}
Gerelateerde regels
- CA2215: Verwijderingsmethoden moeten de basisklasse verwijderen aanroepen
- CA2216: Disposable typen moeten een finalizer declareren