Sdílet prostřednictvím


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;
        }
    }
}