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 9 | 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