Share via


CA2213: Eldobható mezőket kell megsemmisíteni

Tulajdonság Érték
Szabályazonosító CA2213
Cím Eldobható mezőket kell megsemmisíteni
Kategória Használat
A javítás kompatibilitástörő vagy nem törik Nem törés
Alapértelmezés szerint engedélyezve a .NET 8-ban Nem

Ok

Egy olyan típus, amely implementálja System.IDisposable a szintén implementált IDisposabletípusú mezők deklarálását. A Dispose mező metódusát nem a Dispose deklarálási típus metódusa hívja meg.

Szabály leírása

Egy típus felelős az összes nem felügyelt erőforrás eltávolításáért. A CA2213 szabály ellenőrzi, hogy egy eldobható típus (vagyis az azt megvalósító IDisposable) T deklarál-e egy olyan mezőt F , amely egy eldobható típusú FTpéldány. Minden olyan mező F esetében, amely helyileg létrehozott objektumot rendelt a tartalmazó típus Tmetódusaihoz vagy inicializálóihoz FT.Dispose, a szabály megkísérli megkeresni a hívást. A szabály megkeresi a meghívott T.Dispose metódusokat, és egy szinttel alacsonyabb (vagyis a metódusok által T.Disposehívott metódusokat).

Megjegyzés:

A speciális eseteken kívül a CA2213 szabály csak azokra a mezőkre aktiválódik, amelyek helyileg létrehozott eldobható objektumot rendelnek hozzá az adott típus metódusaihoz és inicializálóihoz. Ha az objektumot típuson Tkívül hozzák létre vagy rendelik hozzá, a szabály nem aktiválódik. Ez csökkenti a zajt olyan esetekben, amikor a tartalmazó típus nem felelős az objektum eltávolításáért.

Különleges esetek

A CA2213 szabály akkor is aktiválhatja a következő típusú mezőket, ha a hozzárendelt objektum nincs helyileg létrehozva:

Ha egy ilyen típusú objektumot átad egy konstruktornak, majd egy mezőhöz rendeli, az azt jelenti , hogy az újonnan létrehozott típus tulajdonjogátruházás történik. Vagyis az újonnan létrehozott típus felelős az objektum eltávolításáért. Ha az objektum nincs megsemmisítve, a CA2213 megsértése történik.

Szabálysértések kijavítása

A szabály megsértésének kijavításához hívja meg Dispose a implementálandó IDisposabletípusú mezőket.

Mikor kell letiltani a figyelmeztetéseket?

A szabály figyelmeztetését nyugodtan letilthatja, ha:

  • A megjelölt típus nem felelős a mező által birtokolt erőforrás felszabadításáért (azaz a típus nem rendelkezik elidegenítési tulajdonjogkal)
  • A hívás Dispose mélyebb hívószinten történik, mint a szabály ellenőrzése
  • a mező(ek) elidegenítési tulajdonjogát nem a tartalmú típus birtokolja.

Figyelmeztetés mellőzése

Ha csak egyetlen szabálysértést szeretne letiltani, adjon hozzá előfeldolgozási irányelveket a forrásfájlhoz a szabály letiltásához és újbóli engedélyezéséhez.

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

Ha le szeretné tiltani egy fájl, mappa vagy projekt szabályát, állítsa annak súlyosságát none a konfigurációs fájlban.

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

További információ: Kódelemzési figyelmeztetések letiltása.

Példa

Az alábbi kódrészlet egy implementálható IDisposabletípust TypeA mutat be.

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

Az alábbi kódrészlet egy olyan típust TypeB mutat be, amely megsérti a CA2213 szabályt azáltal, hogy egy mezőt aFieldOfADisposableType eldobható típusként (TypeA) deklarál, és nem hívja meg Dispose a mezőt.

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

A szabálysértés kijavításához hívja fel Dispose() az eldobható mezőt:

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

Kapcsolódó információk