CA2213: Verwerfbare Felder verwerfen.
Eigenschaft | Wert |
---|---|
Regel-ID | CA2213 |
Titel | Verwerfbare Felder verwerfen. |
Kategorie | Verwendung |
Fix führt oder führt nicht zur Unterbrechung | Nicht unterbrechend |
Standardmäßig in .NET 8 aktiviert | Nein |
Ursache
Ein Typ, der System.IDisposable implementiert, deklariert Felder, die auch IDisposable implementieren. Die Dispose-Methode des Felds wird nicht von der Dispose-Methode des deklarierenden Typs aufgerufen.
Regelbeschreibung
Ein Typ ist für die Entsorgung aller seiner nicht verwalteten Ressourcen zuständig. Rule CA2213 prüft, ob ein verwerfbarer Typ (d. h. ein Typ IDisposable, T
der implementiert) ein Feld deklariert F
, das eine Instanz eines verwerfbaren Typs ist FT
. Für jedes Feld, dem F
ein lokal erstelltes Objekt innerhalb der Methoden oder Initialisierer des enthaltenden Typs zugewiesen T
wird, versucht die Regel, einen Aufruf zu ermittelnFT.Dispose
. Die Regel durchsucht die Methoden, die von T.Dispose
aufgerufen werden und eine Ebene tiefer (d. h. die Methoden, die von den von aufgerufenen Methoden aufgerufen werden von T.Dispose
).
Hinweis
Mit Ausnahme der Sonderfällewird Regel CA2213 nur für Felder ausgelöst, denen ein lokal erstelltes verwerfbares Objekt innerhalb der Methoden und Initialisierer des enthaltenden Typs zugewiesen wird. Wenn das Objekt erstellt oder außerhalb des Typs zugewiesen wird T
, wird die Regel nicht ausgelöst. Dies reduziert die Störung in Fällen, in denen der enthaltende Typ nicht die Verantwortung für die Verwerfung des Objekts übernimmt.
Spezialfälle
Regel CA2213 kann auch für Felder der folgenden Typen ausgelöst werden, auch wenn das Objekt, dem Sie zugewiesen sind, nicht lokal erstellt wurde:
Wenn Sie ein Objekt eines dieser Typen an einen Konstruktor übergeben und dann einem Feld zuweisen, wird ein Verwerfen der Eigentumsübertragung an den neu erstellten Typ angegeben. Das heißt, der neu konstruierte Typ ist nun für das Verwerfen des Objekts verantwortlich. Wenn das Objekt nicht verworfen wird, tritt ein Verstoß gegen CA2213 auf.
Behandeln von Verstößen
Um einen Verstoß gegen diese Regel zu beheben, rufen Sie Felder auf, die von Typen Dispose sind, dieIDisposable implementieren.
Wann sollten Warnungen unterdrückt werden?
Eine Warnung aus dieser Regel kann sicher unterdrückt werden, wenn Folgendes gilt:
- Der gekennzeichnete Typ ist nicht für die Freigabe der Ressource zuständig, die im Feld gehalten wird (d. h., der Typ hat keine Verwerfung des Eigentums)
- Der Aufruf zu Dispose erfolgt auf einer tieferen Aufrufebene als die Regelprüfungen erfolgen.
- der Freigabe Besitz der Felder wird nicht vom enthaltenden Typ gehalten.
Unterdrücken einer Warnung
Um nur eine einzelne Verletzung zu unterdrücken, fügen Sie der Quelldatei Präprozessoranweisungen hinzu, um die Regel zu deaktivieren und dann wieder zu aktivieren.
#pragma warning disable CA2213
// The code that's violating the rule is on this line.
#pragma warning restore CA2213
Um die Regel für eine Datei, einen Ordner oder ein Projekt zu deaktivieren, legen Sie den Schweregrad in der Konfigurationsdatei auf none
fest.
[*.{cs,vb}]
dotnet_diagnostic.CA2213.severity = none
Weitere Informationen finden Sie unter Vorgehensweise: Unterdrücken von Codeanalyse-Warnungen.
Beispiel
Der folgende Codeausschnitt zeigt einen Typ TypeA
, der implementiert 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);
}
}
Der folgende Code Ausschnitt zeigt einen Typ TypeB
, der die Regel CA2213 verletzt, indem er ein Feld aFieldOfADisposableType
als verwerfbaren Typ ( TypeA
) deklariert und nicht Dispose für das Feld aufgerufen wird.
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);
}
}
Um die Verletzung zu beheben, müssen Sie das verwerfbare Feld Dispose()
aufrufen:
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);
}
}
}