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


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, StaticConstructoramely megsérti a szabályt és egy típust, NoStaticConstructoramely 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