CA2213: Wegwerpvelden moeten worden verwijderd
Eigenschappen | Weergegeven als |
---|---|
Regel-id | CA2213 |
Titel | Wegwerpvelden moeten worden verwijderd |
Categorie | Gebruik |
Oplossing is brekend of niet-brekend | Niet-brekend |
Standaard ingeschakeld in .NET 9 | Nee |
Oorzaak
Een type waarmee velden worden geïmplementeerd System.IDisposable , declareert velden die ook worden geïmplementeerd IDisposable. De Dispose methode van het veld wordt niet aangeroepen door de Dispose methode van het declaratietype.
Beschrijving van regel
Een type is verantwoordelijk voor het verwijderen van alle onbeheerde resources. Regel CA2213 controleert of een wegwerptype (dat wil zeggen, een die implementeert IDisposable) T
een veld F
declareert dat een exemplaar van een wegwerptype FT
is. Voor elk veld F
waaraan een lokaal gemaakt object is toegewezen binnen de methoden of initialisatiefuncties van het betreffende type T
, probeert de regel een aanroep naar te FT.Dispose
zoeken. De regel doorzoekt de methoden die worden aangeroepen door T.Dispose
en één niveau lager (dat wil gezegd de methoden die worden aangeroepen door de methoden die worden aangeroepen door T.Dispose
).
Notitie
Behalve de speciale gevallen wordt regel CA2213 alleen geactiveerd voor velden waaraan een lokaal gemaakt wegwerpobject is toegewezen binnen de methoden en initialisatiefuncties van het betreffende type. Als het object buiten het type T
is gemaakt of toegewezen, wordt de regel niet geactiveerd. Dit vermindert ruis voor gevallen waarin het type bevat niet de verantwoordelijkheid heeft voor het verwijderen van het object.
Speciale gevallen
Regel CA2213 kan ook worden geactiveerd voor velden van de volgende typen, zelfs als het object waaraan ze zijn toegewezen niet lokaal is gemaakt:
Het doorgeven van een object van een van deze typen aan een constructor en het vervolgens toewijzen aan een veld geeft aan dat het eigendom wordt overgedragen naar het nieuw samengestelde type. Dat wil gezegd, het zojuist gebouwde type is nu verantwoordelijk voor het verwijderen van het object. Als het object niet wordt verwijderd, treedt er een schending van CA2213 op.
Schendingen oplossen
Als u een schending van deze regel wilt oplossen, roept Dispose u velden aan die van de typen die worden geïmplementeerd IDisposable.
Wanneer waarschuwingen onderdrukken
Het is veilig om een waarschuwing van deze regel te onderdrukken als:
- Het gemarkeerde type is niet verantwoordelijk voor het vrijgeven van de resource die door het veld wordt bewaard (dat wil gezegd, het type heeft geen eigendom van de verwijdering)
- De aanroep die Dispose moet worden uitgevoerd op een dieper aanroepniveau dan de regelcontroles
- het eigendom van het verwijderen van de velden wordt niet bewaard door het type dat het bevat.
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 CA2213
// The code that's violating the rule is on this line.
#pragma warning restore CA2213
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.CA2213.severity = none
Zie Codeanalysewaarschuwingen onderdrukken voor meer informatie.
Opmerking
In het volgende fragment ziet u een type TypeA
dat wordt geïmplementeerd IDisposable.
public class TypeA : IDisposable
{
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Dispose managed resources
}
// Free native resources
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Disposable types implement a finalizer.
~TypeA()
{
Dispose(false);
}
}
Het volgende codefragment toont een type TypeB
dat de regel CA2213 schendt door een veld aFieldOfADisposableType
als wegwerptype (TypeA
) te declareren en niet aan te roepen Dispose op het veld.
public class TypeB : IDisposable
{
// Assume this type has some unmanaged resources.
TypeA aFieldOfADisposableType = new TypeA();
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
// Dispose of resources held by this instance.
// Violates rule: DisposableFieldsShouldBeDisposed.
// Should call aFieldOfADisposableType.Dispose();
disposed = true;
// Suppress finalization of this disposed instance.
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
public void Dispose()
{
if (!disposed)
{
// Dispose of resources held by this instance.
Dispose(true);
}
}
// Disposable types implement a finalizer.
~TypeB()
{
Dispose(false);
}
}
Als u de schending wilt oplossen, roept u Dispose()
het wegwerpveld aan:
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
// Dispose of resources held by this instance.
aFieldOfADisposableType.Dispose();
disposed = true;
// Suppress finalization of this disposed instance.
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}