Megosztás a következőn keresztül:


CA2000: Objektumokat szabadít fel a hatókör elvesztése előtt

Tulajdonság Érték
Szabályazonosító CA2000
Cím Objektumok elidegenítése a hatókör elvesztése előtt
Kategória Megbízhatóság
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

Létrejön egy IDisposable helyi típusú objektum, de az objektum nem lesz megsemmisítve, mielőtt az objektumra mutató összes hivatkozás hatókörön kívül esik.

Ez a szabály alapértelmezés szerint a teljes kódbázist elemzi, de ez konfigurálható.

Szabály leírása

Ha egy eldobható objektum nincs explicit módon megsemmisítve, mielőtt az összes rá mutató hivatkozás hatókörön kívül lenne, az objektumot meghatározatlan időpontban kell megsemmisíteni, amikor a szemétgyűjtő futtatja az objektum véglegesítőjét. Mivel előfordulhat olyan kivételes esemény, amely megakadályozza az objektum véglegesítőjének futását, az objektumot explicit módon kell megsemmisíteni.

Különleges esetek

A CA2000 szabály akkor sem aktiválja az alábbi típusú helyi objektumokat, ha az objektum nincs megsemmisítve:

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 a kód átad egy ilyen típusú objektumot egy konstruktornak, akkor a CA2000 szabály megsértése akkor sem történik meg, ha az objektum nincs megsemmisítve, mielőtt az összes hivatkozás hatókörén kívül lenne.

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

A szabály megsértésének kijavításához hívja meg Dispose az objektumot, mielőtt az összes rá mutató hivatkozás hatókörön kívül lenne.

Az utasítással (Usinga using Visual Basicben) körbefuttathatja a implementálandó IDisposableobjektumokat. Az ilyen módon burkolt objektumok automatikusan a blokk végén lesznek using megsemmisítve. A következő helyzeteket azonban nem, vagy nem lehet utasítással using kezelni:

  • Egy eldobható objektum visszaadásához az objektumot blokkon try/finally kívüli using blokkban kell létrehozni.

  • Ne inicializálja egy eldobható objektum tagjait egy utasítás konstruktorában using .

  • Ha a csak egy kivételkezelő által védett konstruktorok egy using utasítás beszerzési részében vannak beágyazva, a külső konstruktor meghibásodása azt eredményezheti, hogy a beágyazott konstruktor által létrehozott objektum soha nem lesz bezárva. Az alábbi példában a StreamReader konstruktor meghibásodása azt eredményezheti, hogy az FileStream objektum soha nem lesz bezárva. A CA2000 ebben az esetben a szabály megsértését jelöli.

    using (StreamReader sr = new StreamReader(new FileStream("C:/myfile.txt", FileMode.Create)))
    { ... }
    
  • A dinamikus objektumoknak árnyékobjektumot kell használniuk az objektumok elidegenítési mintájának implementálásához IDisposable .

Mikor kell letiltani a figyelmeztetéseket?

Ne tiltsa el a szabály figyelmeztetését, kivéve, ha:

  • Olyan metódust hívott meg az objektumon, amely meghívja Disposeazokat, például Close.
  • A figyelmeztetést generáló metódus egy IDisposable objektumot ad vissza, amely körbefuttatja az objektumot.
  • Az allokálási módszer nem rendelkezik tulajdonjog-átruházással; vagyis az objektum elidegenítésének felelőssége egy másik, a metódusban létrehozott és a hívónak visszaadott objektumra vagy burkolóra kerül.

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 CA2000
// The code that's violating the rule is on this line.
#pragma warning restore CA2000

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.CA2000.severity = none

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

Kód konfigurálása elemzéshez

A következő beállítások segítségével konfigurálhatja, hogy a kódbázis mely részein futtassa ezt a szabályt.

Ezeket a beállításokat konfigurálhatja csak erre a szabályra, az összes szabályra, vagy az ebben a kategóriában szereplő összes szabályra (Megbízhatóság), amelyekre vonatkozik. További információ: Kódminőségi szabály konfigurációs beállításai.

Adott szimbólumok kizárása

Bizonyos szimbólumokat, például típusokat és metódusokat kizárhat az elemzésből. Ha például meg szeretné adni, hogy a szabály ne fusson a nevesített MyTypetípusok egyikén sem, adja hozzá a következő kulcs-érték párot a projekt egyik .editorconfig fájljához:

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

Engedélyezett szimbólumnévformátumok a beállításértékben (a következővel |elválasztva):

  • Csak szimbólumnév (a névvel ellátott összes szimbólumot tartalmazza, függetlenül attól, hogy milyen típusú vagy névtérrel rendelkezik).
  • A szimbólum dokumentációazonosító-formátumában szereplő teljes nevek. Minden szimbólumnévhez szimbólum típusú előtag szükséges, például M: metódusokhoz, T: típusokhoz és N: névterekhez.
  • .ctor konstruktorok és .cctor statikus konstruktorok számára.

Példák:

Beállítás értéke Összegzés
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType Megegyezik az összes elnevezett MyTypeszimbólummal.
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 Megegyezik az összes elnevezett MyType1 szimbólummal vagy MyType2.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) Megfelel a megadott metódusnak MyMethod a megadott teljes jogosultsággal rendelkező aláírással.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) Egyezik az adott metódusokkal MyMethod1 és MyMethod2 a megfelelő, teljes mértékben minősített aláírásokkal.

Adott típusok és származtatott típusok kizárása

Bizonyos típusokat és azok származtatott típusait kizárhatja az elemzésből. Ha például meg szeretné adni, hogy a szabály ne fusson a nevesített MyType és származtatott típusok egyik metódusán sem, adja hozzá a következő kulcs-érték párot a projekt egyik .editorconfig fájljához:

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

Engedélyezett szimbólumnévformátumok a beállításértékben (a következővel |elválasztva):

  • Csak típusnév (a névvel rendelkező összes típust tartalmazza, függetlenül attól, hogy milyen típust vagy névteret tartalmaz).
  • A szimbólum dokumentációazonosító-formátumában szereplő teljes nevek opcionális T: előtaggal.

Példák:

Beállítás értéke Összegzés
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType Megfelel az összes névvel ellátott MyType típusnak és az összes származtatott típusnak.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 Megfelel az összes névvel ellátott MyType1 típusnak, vagy MyType2 az összes származtatott típusnak.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType Egyezik MyType a megadott teljes névvel és az összes származtatott típusával.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 Egyezik az adott típusokkal MyType1 és MyType2 a megfelelő teljes névvel, valamint az összes származtatott típussal.

1. példa

Ha olyan metódust implementál, amely eldobható objektumot ad vissza, használjon egy fogási blokk nélküli próbálkozást/végül blokkot, hogy meggyőződjön arról, hogy az objektum el van dobva. Egy próba/végül blokk használatával engedélyezi a kivételeket a hibaponton, és győződjön meg arról, hogy az objektum el van állítva.

Az OpenPort1 metódusban az ISerializable objektum SerialPort vagy a SomeMethod hívása sikertelen lehet. A megvalósítás során CA2000 figyelmeztetés jelenik meg.

Az OpenPort2 metódusban két SerialPort-objektum deklarálva van, és null értékre van állítva:

  • tempPort, amely a metódusműveletek sikerességét teszteli.

  • port, amelyet a metódus visszatérési értékéhez használnak.

A tempPort blokk egy try blokkban van létrehozva és megnyitva, és minden más szükséges munka ugyanabban try a blokkban történik. A blokk végén a try megnyitott port hozzá lesz rendelve a port visszaadott objektumhoz, és az tempPort objektum értéke null.

A finally blokk ellenőrzi a következő értékét tempPort: . Ha nem null értékű, a metódus egyik művelete sikertelen volt, és tempPort bezárva van, hogy meggyőződjön arról, hogy az erőforrások felszabadulnak. A visszaadott portobjektum a megnyitott SerialPort objektumot fogja tartalmazni, ha a metódus műveletei sikeresek, vagy null értékű lesz, ha egy művelet meghiúsult.

public SerialPort OpenPort1(string portName)
{
   SerialPort port = new SerialPort(portName);
   port.Open();  //CA2000 fires because this might throw
   SomeMethod(); //Other method operations can fail
   return port;
}

public SerialPort OpenPort2(string portName)
{
   SerialPort tempPort = null;
   SerialPort port = null;
   try
   {
      tempPort = new SerialPort(portName);
      tempPort.Open();
      SomeMethod();
      //Add any other methods above this line
      port = tempPort;
      tempPort = null;

   }
   finally
   {
      if (tempPort != null)
      {
         tempPort.Close();
      }
   }
   return port;
}
Public Function OpenPort1(ByVal PortName As String) As SerialPort

   Dim port As New SerialPort(PortName)
   port.Open()    'CA2000 fires because this might throw
   SomeMethod()   'Other method operations can fail
   Return port

End Function

Public Function OpenPort2(ByVal PortName As String) As SerialPort

   Dim tempPort As SerialPort = Nothing
   Dim port As SerialPort = Nothing

   Try
      tempPort = New SerialPort(PortName)
      tempPort.Open()
      SomeMethod()
      'Add any other methods above this line
      port = tempPort
      tempPort = Nothing

   Finally
      If Not tempPort Is Nothing Then
         tempPort.Close()
      End If

   End Try

   Return port

End Function

2. példa

Alapértelmezés szerint a Visual Basic fordítóban minden számtani operátor ellenőrzi a túlcsordulást. Ezért bármely Visual Basic-aritmetikai művelet dobhat egy OverflowException. Ez olyan szabályok váratlan megsértéséhez vezethet, mint a CA2000. Az alábbi CreateReader1 függvény például CA2000-es szabálysértést eredményez, mert a Visual Basic fordító túlcsordulás-ellenőrzési utasítást bocsát ki az összeadáshoz, amely kivételt okozhat, amely miatt a StreamReader nem lesz megsemmisítve.

Ennek kijavításához letilthatja a Visual Basic fordító által a projektben végzett túlcsordulás-ellenőrzések kibocsátását, vagy módosíthatja a kódot az alábbi CreateReader2 függvényhez hasonlóan.

A túlcsordulás-ellenőrzések kibocsátásának letiltásához kattintson a jobb gombbal a projekt nevére Megoldáskezelő, majd válassza a Tulajdonságok lehetőséget. Válassza a Fordítás>speciális fordítási beállításai lehetőséget, majd jelölje be az Egész szám túlcsordulási ellenőrzéseinek eltávolítása jelölőnégyzetet.

Imports System.IO

Class CA2000
    Public Function CreateReader1(ByVal x As Integer) As StreamReader
        Dim local As New StreamReader("C:\Temp.txt")
        x += 1
        Return local
    End Function


    Public Function CreateReader2(ByVal x As Integer) As StreamReader
        Dim local As StreamReader = Nothing
        Dim localTemp As StreamReader = Nothing
        Try
            localTemp = New StreamReader("C:\Temp.txt")
            x += 1
            local = localTemp
            localTemp = Nothing
        Finally
            If (Not (localTemp Is Nothing)) Then
                localTemp.Dispose()
            End If
        End Try
        Return local
    End Function
End Class

Lásd még