CA1063: Implementuje správně IDisposable
TypeName |
ImplementIDisposableCorrectly |
CheckId |
CA1063 |
Kategorie |
Microsoft.Design |
Narušující změna |
Nenarušující |
Příčina
IDisposable není správně naimplementováno.Zde jsou uvedeny některé důvody potíží:
IDisposable je v rámci třídy znovu implementováno.
Metoda finalize je znovu přepsána.
Metoda Dispose je přepsána.
Metoda Dispose() není veřejná, ani se není pojmenovaná Dispose.
Metoda Dispose(Bool) není chráněná, virtuální nebo neuzavřená.
V neuzavřených typy musí metoda Dispose() volat metodu Dispose(true).
Při použití neuzavřených typů nevolá implementace metody Finalize metodu Dispose(bool) ani finalizační metodu třídy případu.
Porušení některého z těchto vzorů spustí toto upozornění.
Každý neuzavřený kořenový typ IDisposable musí poskytnout vlastní metodu protected virtual void Dispose(bool).Metoda Dispose() by měla volat metodu Dispose(true) a metoda Finalize by měla volat metodu Dispose(false).Při vytváření neuzavřeného kořenového typu IDisposable je zapotřebí definovat a zavolat metodu Dispose(bool).Další informace naleznete v Vymazání nespravovaných prostředků v sekci Design Guidelines for Developing Class LIbraries dokumentace rozhraní .NET Framework.
Popis pravidla
Všechny typy IDisposable by měly správně implementovat vzor Dispose.
Jak vyřešit porušení
Zkontrolujte kód a určete, které z následujících řešení napraví toto porušení.
Odeberte IDisposable ze seznamu rozhraní implementovaných pomocí {0} a místo toho přepište implementaci Dispose základní třídy.
Odeberte finalizační metodu z typu {0}, přepište Dispose (bool disposing) a vložte finalizační logiku do cesty kódu, kde je hodnota 'disposing' rovna hodnotě false.
Odeberte {0}, přepište metodu Dispose (bool disposing) a vložte finalizační logiku do cesty kódu, kde je hodnota 'disposing' rovna hodnotě true.
Zajistěte, že {0} je deklarována jako veřejná a zapečetěná.
Přejmenujte {0} na 'Dispose' a zajistěte, aby byla deklarována jako veřejná a byla zapečetěná.
Ujistěte se, zda je {0} deklarována jako chráněná, virtuální a nezapečetěná.
Upravte {0} tak, aby volala metodu Dispose(true) a poté volala GC.SupressFinalize na aktuální instanci objektu ('this' nebo 'Me' v rámci Visual Basic) a poté vrátila.
Upravte {0} tak, aby volala metodu Dispose(false) a aby následně došlo k návratu.
Při psaní neuzavřené kořenové třídy IDisposables je zapotřebí se ujistit, zda implementace IDisposable kopíruje vzor, který je popsán výše v rámci této části.
Kdy potlačit upozornění
Nepotlačujte upozornění na toto pravidlo.
Příklad v pseudokódu
Následující pseudo kód poskytuje obecný příklad jak implementovat metodu Dispose(bool) v rámci třídy, která používá spravované a nativní zdroje.
public class Resource : IDisposable
{
private IntPtr nativeResource = Marshal.AllocHGlobal(100);
private AnotherResource managedResource = new AnotherResource();
// Dispose() calls Dispose(true)
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// NOTE: Leave out the finalizer altogether if this class doesn't
// own unmanaged resources itself, but leave the other methods
// exactly as they are.
~Resource()
{
// Finalizer calls Dispose(false)
Dispose(false);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// free managed resources
if (managedResource != null)
{
managedResource.Dispose();
managedResource = null;
}
}
// free native resources if there are any.
if (nativeResource != IntPtr.Zero)
{
Marshal.FreeHGlobal(nativeResource);
nativeResource = IntPtr.Zero;
}
}
}