CA2213 : Les champs pouvant être supprimés doivent l'être
TypeName |
DisposableFieldsShouldBeDisposed |
CheckId |
CA2213 |
Catégorie |
Microsoft.Usage |
Modification avec rupture |
Modification sans rupture |
Cause
Un type qui implémente System.IDisposable déclare des champs qui constituent des types qui implémentent eux aussi IDisposable. La méthode Dispose du champ n'est pas appelée par la méthode Dispose du type déclarant.
Description de la règle
Un type est chargé de se débarrasser de toutes ses ressources non managées ; cette opération est effectuée en implémentant IDisposable. Cette règle s'assure qu'un type T pouvant être supprimé déclare un champ F qui constitue une instance d'un type FT pouvant être supprimé. Pour chaque champ F, la règle essaie de localiser un appel à FT.Dispose. La règle applique une recherche aux méthodes appelées par T.Dispose, et à un niveau inférieur (les méthodes appelées par les méthodes appelées par FT.Dispose).
Comment corriger les violations
Pour corriger une violation de cette règle, appelez Dispose sur des champs qui constituent des types qui implémentent IDisposable si vous êtes chargé d'allouer et de libérer les ressources non managées détenues par le champ.
Quand supprimer les avertissements
Il est possible de supprimer sans risque un avertissement de cette règle si vous n'êtes pas chargé de libérer la ressource détenue par le champ ou si l'appel à Dispose se produit à un niveau d'appel inférieur à celui que la règle contrôle.
Exemple
L'exemple suivant présente un type TypeA qui implémente IDisposable (FT dans l'examen précédent).
using System;
namespace UsageLibrary
{
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);
}
}
}
L'exemple suivant affiche un type TypeB qui viole cette règle en déclarant un champ aFieldOfADisposableType (F dans la discussion précédente) comme un type pouvant être supprimé (TypeA) et en n'appelant pas le champ Dispose. TypeB correspond à T dans la discussion précédente.
using System;
namespace UsageLibrary
{
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);
}
}
}
Voir aussi
Référence
Implémentation des méthodes Finalize et Dispose pour nettoyer des ressources non managées