CA2213: Uvolnitelné pole by mělo být uvolněno

Vlastnost Hodnota
ID pravidla CA2213
Název Likvidovatelná pole by měla být likvidována
Kategorie Využití
Oprava, která může být destruktivní nebo nedestruktivní Nezlomitelný
Povoleno ve výchozím nastavení v .NET 10 Ne
Příslušné jazyky C# a Visual Basic

Příčina

Typ, který implementuje System.IDisposable, deklaruje pole, která jsou typy, jež také implementují IDisposable. Dispose Metoda pole není volána Dispose metodou deklarujícího typu.

Popis pravidla

Typ zodpovídá za likvidaci všech nespravovaných prostředků. Pravidlo CA2213 zkontroluje, jestli typ na jedno použití (tj. ten, který implementuje IDisposable) T deklaruje pole F , které je instancí jednorázového typu FT. Pro každé pole F, kterému je přiřazen místně vytvořený objekt v metodách nebo inicializátorech obsahujícího typu T, se pravidlo pokusí najít volání FT.Dispose. Pravidlo hledá metody volané podle T.Dispose a jednu úroveň nižší (to znamená metody volané metodami T.Dispose).

Poznámka:

Kromě zvláštních případů se pravidlo CA2213 aktivuje pouze pro pole, která jsou přiřazena místně vytvořenému uvolnitelnému objektu v rámci metod a inicializátorů typu. Pokud je objekt vytvořen nebo přiřazen mimo typ T, pravidlo se neaktivuje. To snižuje šum v případech, kdy typ obsahujícího objektu nevlastní odpovědnost za likvidaci objektu.

Zvláštní případy

Pravidlo CA2213 se také může aktivovat pro pole následujících typů, i když se objekt, který jsou přiřazený, nevytvoří místně:

Předání objektu jednoho z těchto typů konstruktoru a jeho přiřazení do pole označuje převod vlastnictví s uvolněním zdrojů na nově vytvořený typ. To znamená, že nově vytvořený typ je nyní zodpovědný za likvidaci objektu. Pokud objekt není odstraněn, dojde k porušení CA2213.

Jak opravit porušení

Chcete-li opravit porušení tohoto pravidla, zavolejte Dispose pole, která jsou typu, které implementují IDisposable.

Kdy potlačit upozornění

Upozornění z tohoto pravidla je bezpečné potlačit, pokud:

  • Typ označený příznakem neodpovídá za uvolnění prostředku uchovávaného polem (to znamená, že typ nemá likvidní vlastnictví).
  • Volání Dispose probíhá na hlubší úrovni, než na které pravidlo provádí kontrolu.
  • vlastnictví pole/ů není spravováno obsahujícím typem.

Potlačení upozornění

Pokud chcete pouze potlačit jedno porušení, přidejte do zdrojového souboru direktivy preprocesoru, abyste pravidlo zakázali a znovu povolili.

#pragma warning disable CA2213
// The code that's violating the rule is on this line.
#pragma warning restore CA2213

Pokud chcete pravidlo pro soubor, složku nebo projekt zakázat, nastavte jeho závažnost v none konfiguračním souboru.

[*.{cs,vb}]
dotnet_diagnostic.CA2213.severity = none

Další informace naleznete v tématu Jak potlačit upozornění analýzy kódu.

Konfigurace analýzy toku dat

Ke konfiguraci analýzy toku dat pro toto pravidlo použijte následující možnosti:

Tyto možnosti můžete nakonfigurovat jenom pro toto pravidlo, pro všechna pravidla, která platí pro, nebo pro všechna pravidla v této kategorii (zabezpečení), na která se vztahují. Další informace najdete v tématu možnosti konfigurace pravidla kvality kódu.

Příklad

Následující fragment kódu ukazuje typ TypeA , který implementuje 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);
    }
}

Následující fragment kódu ukazuje typ TypeB , který porušuje pravidlo CA2213 tím, že deklaruje pole aFieldOfADisposableType jako uvolnitelný typ (TypeA) a nevolá Dispose na toto pole.

public class TypeB : IDisposable
{
    // Assume this type has some unmanaged resources.
    TypeA aFieldOfADisposableType = new();
    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);
    }
}

Chcete-li opravit porušení, zavolejte Dispose() na uvolnitelné pole:

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

Viz také