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:
- System.IO.Stream
- System.IO.StringReader
- System.IO.TextReader
- System.IO.TextWriter
- System.Resources.IResourceReader
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 (Using
a 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üliusing
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
Dispose
azokat, 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 MyType
tí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 ésN:
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 MyType szimbó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. |
Kapcsolódó szabályok
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
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: