CA2213: Disponibla fält ska kasseras
Property | Värde |
---|---|
Regel-ID | CA2213 |
Title | Disponibla fält ska kasseras |
Kategori | Användning |
Korrigeringen är icke-bakåtkompatibel | Icke-icke-bryta |
Aktiverad som standard i .NET 9 | Nej |
Orsak
En typ som implementerar System.IDisposable deklarerar fält som är av typer som även implementerar IDisposable. Metoden Dispose för fältet anropas inte av Dispose metoden för deklareringstypen.
Regelbeskrivning
En typ ansvarar för att ta bort alla dess ohanterade resurser. Regel CA2213 kontrollerar om en engångstyp (det vill säga en som implementerar IDisposable) T
deklarerar ett fält F
som är en instans av en engångstyp FT
. För varje fält F
som har tilldelats ett lokalt skapat objekt inom metoderna eller initierarna av den innehållande typen T
försöker regeln hitta ett anrop till FT.Dispose
. Regeln söker igenom de metoder som anropas av T.Dispose
och en nivå lägre (det vill: de metoder som anropas av metoderna som anropas av T.Dispose
).
Kommentar
Förutom specialfallen utlöses endast regel CA2213 för fält som tilldelas ett lokalt skapat engångsobjekt inom den innehållande typens metoder och initialiserare. Om objektet skapas eller tilldelas utanför typen T
utlöses inte regeln. Detta minskar bruset för fall där den innehållande typen inte äger ansvaret för att ta bort objektet.
Särskilda fall
Regel CA2213 kan också utlösas för fält av följande typer även om objektet de tilldelas inte skapas lokalt:
Att skicka ett objekt av någon av dessa typer till en konstruktor och sedan tilldela det till ett fält anger en överföring av ägarskap till den nyligen konstruerade typen. Det innebär att den nyligen konstruerade typen nu ansvarar för att ta bort objektet. Om objektet inte tas bort sker en överträdelse av CA2213.
Så här åtgärdar du överträdelser
Om du vill åtgärda ett brott mot den här regeln anropar du Dispose fält som är av typer som implementerar IDisposable.
När du ska ignorera varningar
Det är säkert att ignorera en varning från den här regeln om:
- Den flaggade typen ansvarar inte för att frigöra resursen som innehas av fältet (det vill: typen har inte ägarskap för bortskaffande)
- Anropet till Dispose sker på en djupare anropsnivå än regelkontrollerna
- ägarskapet för fälten inte innehas av den innehållande typen.
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 CA2213
// The code that's violating the rule is on this line.
#pragma warning restore CA2213
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.CA2213.severity = none
Mer information finns i Så här utelämnar du kodanalysvarningar.
Exempel
Följande kodfragment visar en typ TypeA
som implementerar 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);
}
}
Följande kodfragment visar en typ TypeB
som bryter mot regeln CA2213 genom att deklarera ett fält aFieldOfADisposableType
som en engångstyp (TypeA
) och inte anropa Dispose i fältet.
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);
}
}
Om du vill åtgärda överträdelsen anropar du Dispose()
disponibelt fält:
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);
}
}
}