Delen via


CA2213: Wegwerpvelden moeten worden verwijderd

Eigenschappen Weergegeven als
Regel-id CA2213
Titel Wegwerpvelden moeten worden verwijderd
Categorie Gebruik
Oplossing is brekend of niet-brekend Niet-brekend
Standaard ingeschakeld in .NET 8 Nee

Oorzaak

Een type waarmee velden worden geïmplementeerd System.IDisposable , declareert velden die ook worden geïmplementeerd IDisposable. De Dispose methode van het veld wordt niet aangeroepen door de Dispose methode van het declaratietype.

Beschrijving van regel

Een type is verantwoordelijk voor het verwijderen van alle onbeheerde resources. Regel CA2213 controleert of een wegwerptype (dat wil zeggen, een die implementeert IDisposable) T een veld F declareert dat een exemplaar van een wegwerptype FTis. Voor elk veld F waaraan een lokaal gemaakt object is toegewezen binnen de methoden of initialisatiefuncties van het betreffende type T, probeert de regel een aanroep naar te FT.Disposezoeken. De regel doorzoekt de methoden die worden aangeroepen door T.Dispose en één niveau lager (dat wil gezegd de methoden die worden aangeroepen door de methoden die worden aangeroepen door T.Dispose).

Notitie

Behalve de speciale gevallen wordt regel CA2213 alleen geactiveerd voor velden waaraan een lokaal gemaakt wegwerpobject is toegewezen binnen de methoden en initialisatiefuncties van het betreffende type. Als het object buiten het type Tis gemaakt of toegewezen, wordt de regel niet geactiveerd. Dit vermindert ruis voor gevallen waarin het type bevat niet de verantwoordelijkheid heeft voor het verwijderen van het object.

Speciale gevallen

Regel CA2213 kan ook worden geactiveerd voor velden van de volgende typen, zelfs als het object waaraan ze zijn toegewezen niet lokaal is gemaakt:

Het doorgeven van een object van een van deze typen aan een constructor en het vervolgens toewijzen aan een veld geeft aan dat het eigendom wordt overgedragen naar het nieuw samengestelde type. Dat wil gezegd, het zojuist gebouwde type is nu verantwoordelijk voor het verwijderen van het object. Als het object niet wordt verwijderd, treedt er een schending van CA2213 op.

Schendingen oplossen

Als u een schending van deze regel wilt oplossen, roept Dispose u velden aan die van de typen die worden geïmplementeerd IDisposable.

Wanneer waarschuwingen onderdrukken

Het is veilig om een waarschuwing van deze regel te onderdrukken als:

  • Het gemarkeerde type is niet verantwoordelijk voor het vrijgeven van de resource die door het veld wordt bewaard (dat wil gezegd, het type heeft geen eigendom van de verwijdering)
  • De aanroep die Dispose moet worden uitgevoerd op een dieper aanroepniveau dan de regelcontroles
  • het eigendom van het verwijderen van de velden wordt niet bewaard door het type dat het bevat.

Een waarschuwing onderdrukken

Als u slechts één schending wilt onderdrukken, voegt u preprocessorrichtlijnen toe aan uw bronbestand om de regel uit te schakelen en vervolgens opnieuw in te schakelen.

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

Als u de regel voor een bestand, map of project wilt uitschakelen, stelt u de ernst none ervan in op het configuratiebestand.

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

Zie Codeanalysewaarschuwingen onderdrukken voor meer informatie.

Voorbeeld

In het volgende fragment ziet u een type TypeA dat wordt geïmplementeerd 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);
    }
}

Het volgende codefragment toont een type TypeB dat de regel CA2213 schendt door een veld aFieldOfADisposableType als wegwerptype (TypeA) te declareren en niet aan te roepen Dispose op het veld.

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

Als u de schending wilt oplossen, roept u Dispose() het wegwerpveld aan:

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

Zie ook