CA1810: Referenciatípus statikus mezőinek inicializálása beágyazottan
Tulajdonság | Érték |
---|---|
Szabályazonosító | CA1810 |
Cím | Referenciatípus statikus mezőinek inicializálása beágyazottan |
Kategória | Teljesítmény |
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
A referenciatípus explicit statikus konstruktort deklarál.
Szabály leírása
Amikor egy típus explicit statikus konstruktort deklarál, a just-in-time (JIT) fordító egy ellenőrzést ad hozzá a típus minden egyes statikus metódusához és példánykonstruktorához, hogy meggyőződjön arról, hogy a statikus konstruktort korábban meghívták. A statikus inicializálás bármely statikus tag elérésekor vagy egy ilyen típusú példány létrehozásakor aktiválódik. A statikus inicializálás azonban nem aktiválódik, ha deklarál egy ilyen típusú változót, de nem használja azt, ami fontos lehet, ha az inicializálás globális állapotot módosít.
Ha az összes statikus adat inicializálva van, és nem deklarál egy explicit statikus konstruktort, a közös köztes nyelv (CIL) fordítói hozzáadják a beforefieldinit
jelölőt és egy implicit statikus konstruktort, amely inicializálja a statikus adatokat a CIL típusdefiníciójában. Amikor a JIT-fordító találkozik a beforefieldinit
jelölőkkel, a statikus konstruktor ellenőrzései legtöbbször nem lesznek hozzáadva. A statikus inicializálás garantáltan valamikor a statikus mezők elérése előtt következik be, de statikus metódus vagy példánykonstruktor meghívása előtt nem. Vegye figyelembe, hogy a statikus inicializálás bármikor megtörténhet egy ilyen típusú változó deklarálása után.
A statikus konstruktor-ellenőrzések csökkenthetik a teljesítményt. A statikus konstruktorok gyakran csak statikus mezők inicializálására szolgálnak, ebben az esetben csak a statikus mező első elérése előtt kell meggyőződnie arról, hogy a statikus inicializálás történik. A beforefieldinit
viselkedés ezekhez és a legtöbb más típushoz megfelelő. Ez csak akkor helytelen, ha a statikus inicializálás hatással van a globális állapotra, és az alábbiak egyike igaz:
A globális állapotra gyakorolt hatás költséges, és nem szükséges, ha a típust nem használják.
A globális állapoteffektusok a típus bármely statikus mezőjének elérése nélkül érhetők el.
Szabálysértések kijavítása
A szabály megsértésének kijavításához inicializálja az összes statikus adatot a deklaráláskor, és távolítsa el a statikus konstruktort.
Mikor kell letiltani a figyelmeztetéseket?
Ha az alábbiak valamelyike érvényes, nyugodtan letilthat egy figyelmeztetést ebből a szabályból:
- A teljesítmény nem aggodalomra ad okot.
- A statikus inicializálás által okozott globális állapotváltozások költségesek, vagy garantáltan bekövetkeznek a típus statikus metódusának meghívása vagy a típus egy példányának létrehozása előtt.
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 CA1810
// The code that's violating the rule is on this line.
#pragma warning restore CA1810
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.CA1810.severity = none
További információ: Kódelemzési figyelmeztetések letiltása.
Példa
Az alábbi példa egy olyan típust mutat be, StaticConstructor
amely megsérti a szabályt és egy típust, NoStaticConstructor
amely a statikus konstruktort beágyazott inicializálásra cseréli a szabály kielégítése érdekében.
public class StaticConstructor
{
static int someInteger;
static string? resourceString;
static StaticConstructor()
{
someInteger = 3;
ResourceManager stringManager =
new ResourceManager("strings", Assembly.GetExecutingAssembly());
resourceString = stringManager.GetString("string");
}
public void Print()
{
Console.WriteLine(someInteger);
}
}
public class NoStaticConstructor
{
static int someInteger = 3;
static string? resourceString = InitializeResourceString();
static string? InitializeResourceString()
{
ResourceManager stringManager =
new ResourceManager("strings", Assembly.GetExecutingAssembly());
return stringManager.GetString("string");
}
public void Print()
{
Console.WriteLine(someInteger);
}
}
Imports System
Imports System.Resources
Namespace ca1810
Public Class StaticConstructor
Shared someInteger As Integer
Shared resourceString As String
Shared Sub New()
someInteger = 3
Dim stringManager As New ResourceManager("strings",
System.Reflection.Assembly.GetExecutingAssembly())
resourceString = stringManager.GetString("string")
End Sub
End Class
Public Class NoStaticConstructor
Shared someInteger As Integer = 3
Shared resourceString As String = InitializeResourceString()
Private Shared Function InitializeResourceString()
Dim stringManager As New ResourceManager("strings",
System.Reflection.Assembly.GetExecutingAssembly())
Return stringManager.GetString("string")
End Function
End Class
End Namespace
Figyelje meg a beforefieldinit
jelölő hozzáadását az osztály CIL-definícióján NoStaticConstructor
.
.class public auto ansi StaticConstructor
extends [mscorlib]System.Object
{
} // end of class StaticConstructor
.class public auto ansi beforefieldinit NoStaticConstructor
extends [mscorlib]System.Object
{
} // end of class NoStaticConstructor
Kapcsolódó szabályok
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: