CA1063: IDisposable correct implementeren
Eigenschappen | Weergegeven als |
---|---|
Regel-id | CA1063 |
Titel | IDisposable correct implementeren |
Categorie | Ontwerpen |
Oplossing is brekend of niet-brekend | Niet-brekend |
Standaard ingeschakeld in .NET 9 | Nee |
Oorzaak
De System.IDisposable interface is niet correct geïmplementeerd. Mogelijke redenen hiervoor zijn:
- IDisposable wordt opnieuw gebruikt in de klasse.
Finalize
wordt opnieuw overschreven.Dispose()
wordt overschreven.- De
Dispose()
methode is niet openbaar, verzegeld of met de naam Dispose. Dispose(bool)
is niet beveiligd, virtueel of niet-verzegeld.- In niet-verzegelde typen
Dispose()
moet worden aangeroepenDispose(true)
. - Voor niet-verzegelde typen roept de
Finalize
implementatie geen of beideDispose(bool)
of de finalizer van de basisklasse aan.
Schending van een van deze patronen activeert waarschuwing CA1063.
Elk niet-verzegeld type dat de IDisposable interface declareert en implementeert, moet een eigen protected virtual void Dispose(bool)
methode bieden. Dispose()
moet worden aangeroepen Dispose(true)
en de finalizer moet worden aangeroepen Dispose(false)
. Als u een niet-verzegeld type maakt dat de IDisposable interface declareert en implementeert, moet u deze definiëren Dispose(bool)
en aanroepen. Zie de handleiding onbeheerde resources (.NET) opschonen en een verwijderingsmethode implementeren voor meer informatie.
Deze regel kijkt standaard alleen naar extern zichtbare typen, maar dit kan worden geconfigureerd.
Beschrijving van regel
Alle IDisposable typen moeten het verwijderingspatroon correct implementeren.
Schendingen oplossen
Controleer uw code en bepaal welke van de volgende oplossingen deze schending verhelpt:
Verwijder IDisposable uit de lijst met interfaces die door uw type zijn geïmplementeerd en overschrijf in plaats daarvan de implementatie van de basisklasse Verwijderen.
Verwijder de finalizer uit uw type, overschrijf Verwijdering (verwijderen van bool) en plaats de finalisatielogica in het codepad waar 'verwijderen' onwaar is.
Override Dispose(bool disponeren) en plaats de verwijderingslogica in het codepad waar 'verwijderen' waar is.
Zorg ervoor dat Dispose() is gedeclareerd als openbaar en verzegeld.
Wijzig de naam van de verwijderingsmethode om te verwijderen en zorg ervoor dat deze is gedeclareerd als openbaar en verzegeld.
Zorg ervoor dat Dispose(bool) is gedeclareerd als beveiligd, virtueel en niet-verzegeld.
Wijzig Dispose() zodat deze Dispose(true) aanroept, roept vervolgens SuppressFinalize het huidige objectexemplaren (
this
ofMe
in Visual Basic) aan en retourneert vervolgens.Pas uw finalizer aan zodat deze Verwijdering (onwaar) aanroept en vervolgens wordt geretourneerd.
Als u een niet-verzegeld type maakt dat de IDisposable interface declareert en implementeert, moet u ervoor zorgen dat de implementatie van IDisposable het patroon volgt dat eerder in deze sectie wordt beschreven.
Wanneer waarschuwingen onderdrukken
Een waarschuwing van deze regel niet onderdrukken.
Notitie
U ziet mogelijk fout-positieve waarschuwingen van deze regel als alle volgende van toepassing zijn:
- U gebruikt Visual Studio 2022 versie 17.5 of hoger met een oudere versie van de .NET SDK, dat wil zeggen .NET 6 of eerder.
- U gebruikt de analyses van de .NET 6 SDK of een oudere versie van de analysepakketten, zoals Microsoft.CodeAnalysis.FxCopAnalyzers.
- U hebt kenmerken voor uw
IDispose
implementatie.
In dit geval is het veilig om een fout-positieve waarschuwing te onderdrukken. De fout-positieven zijn te wijten aan een wijziging die fouten veroorzaakt in de C#-compiler. Overweeg om een nieuwere analyse te gebruiken die de oplossing voor de fout-positieve waarschuwingen bevat. Voer een upgrade uit naar Microsoft.CodeAnalysis.NetAnalyzers versie 7.0.0-preview1.22464.1 of hoger of gebruik de analyses van de .NET 7 SDK.
Code configureren om te analyseren
Gebruik de volgende optie om te configureren op welke onderdelen van uw codebase deze regel moet worden uitgevoerd.
U kunt deze optie configureren voor alleen deze regel, voor alle regels waarop deze van toepassing is, of voor alle regels in deze categorie (ontwerp) waarop deze van toepassing is. Zie de configuratieopties voor de codekwaliteitsregel voor meer informatie.
Specifieke API-oppervlakken opnemen
U kunt instellen op welke onderdelen van uw codebase deze regel moet worden uitgevoerd, op basis van hun toegankelijkheid. Als u bijvoorbeeld wilt opgeven dat de regel alleen moet worden uitgevoerd op het niet-openbare API-oppervlak, voegt u het volgende sleutel-waardepaar toe aan een .editorconfig-bestand in uw project:
dotnet_code_quality.CAXXXX.api_surface = private, internal
Voorbeeld van pseudocode
De volgende pseudocode biedt een algemeen voorbeeld van hoe Dispose(bool)
moet worden geïmplementeerd in een klasse die gebruikmaakt van beheerde en systeemeigen resources.
public class Resource : IDisposable
{
private bool isDisposed;
private IntPtr nativeResource = Marshal.AllocHGlobal(100);
private AnotherResource managedResource = new AnotherResource();
// Dispose() calls Dispose(true)
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
protected virtual void Dispose(bool disposing)
{
if (isDisposed) return;
if (disposing)
{
// free managed resources
managedResource.Dispose();
}
// free native resources if there are any.
if (nativeResource != IntPtr.Zero)
{
Marshal.FreeHGlobal(nativeResource);
nativeResource = IntPtr.Zero;
}
isDisposed = true;
}
// NOTE: Leave out the finalizer altogether if this class doesn't
// own unmanaged resources, but leave the other methods
// exactly as they are.
~Resource()
{
// Finalizer calls Dispose(false)
Dispose(false);
}
}