Bagikan melalui


CA1810: Inisialisasi bidang statik jenis referensi sebaris

Properti Nilai
ID Aturan CA1810
Judul Inisialisasi bidang statik jenis referensi sebaris
Golongan Performa
Perbaikan bersifat disruptif atau non-disruptif Non-disruptif
Diaktifkan secara default di .NET 8 No

Penyebab

Jenis referensi mendeklarasikan konstruktor statik eksplisit.

Deskripsi aturan

Ketika jenis mendeklarasikan konstruktor statik eksplisit, kompilator just-in-time (JIT) menambahkan tanda centang ke setiap metode statik dan konstruktor instans dari jenis tersebut untuk memastikan bahwa konstruktor statik telah dipanggil sebelumnya. Inisialisasi statik dipicu ketika setiap anggota statis diakses atau saat instans jenis dibuat. Namun, inisialisasi statik tidak dipicu jika Anda mendeklarasikan variabel jenis tetapi tidak menggunakannya, yang mungkin diperlukan jika inisialisasi mengubah status global.

Ketika semua data statis diinisialisasi sebaris dan konstruktor statis eksplisit tidak dideklarasikan, pengkompilasi bahasa perantara umum (CIL) menambahkan beforefieldinit bendera dan konstruktor statis implisit, yang menginisialisasi data statis, ke definisi jenis CIL. Ketika pengompilasi JIT menemukan bendera beforefieldinit, sebagian besar waktu pemeriksaan konstruktor statis tidak ditambahkan. Inisialisasi statik dijamin terjadi pada kapan saja sebelum bidang statik diakses, tetapi bukan sebelum metode statik atau konstruktor instans dipanggil. Perhatikan bahwa inisialisasi statik dapat terjadi kapan saja setelah variabel jenis dideklarasikan.

Pemeriksaan konstruktor statik dapat menurunkan performa. Konstruktor statik sering digunakan untuk menginisialisasi bidang statik saja, dalam hal ini Anda hanya perlu memastikan bahwa inisialisasi statik terjadi sebelum akses pertama bidang statik. Perilaku beforefieldinit sesuai untuk jenis ini dan sebagian besar jenis lainnya. Perilaku ini hanya tidak sesuai ketika inisialisasi statis memengaruhi status global dan salah satu dari hal berikut terjadi:

  • Efek pada status global mahal dan tidak diperlukan jika jenisnya tidak digunakan.

  • Efek status global dapat diakses tanpa mengakses bidang statik jenis apa pun.

Cara memperbaiki pelanggaran

Untuk memperbaiki pelanggaran aturan ini, inisialisasi semua data statis saat dideklarasikan dan hapus konstruktor statik.

Kapan harus menekan peringatan

Anda dapat menyembunyikan peringatan dari aturan ini jika salah satu hal berikut ini berlaku:

  • Performa bukanlah perhatian utama.
  • Perubahan status global yang disebabkan oleh inisialisasi statik memerlukan banyak sumber daya atau harus dijamin terjadi sebelum metode statik jenis dipanggil atau instans jenis dibuat.

Menyembunyikan peringatan

Jika Anda hanya ingin menyembunyikan satu pelanggaran, tambahkan arahan praprosedur ke file sumber Anda untuk dinonaktifkan lalu aktifkan kembali aturannya.

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

Untuk menonaktifkan aturan untuk file, folder, atau proyek, atur tingkat keparahannya ke none dalam file konfigurasi.

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

Untuk informasi selengkapnya, lihat Cara menyembunyikan peringatan analisis kode.

Contoh

Contoh berikut menunjukkan jenis StaticConstructor yang melanggar aturan dan jenis NoStaticConstructor dan menggantikan konstruktor statik dengan inisialisasi sebaris untuk memenuhi aturan.

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

Perhatikan penambahan beforefieldinit bendera pada definisi CIL untuk NoStaticConstructor kelas .

.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