Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Konstruktor statik digunakan untuk menginisialisasi data statik apa pun, atau untuk melakukan tindakan tertentu yang perlu dilakukan hanya sekali. Ini dipanggil secara otomatis sebelum instans pertama dibuat atau anggota statis apa pun direferensikan. Konstruktor statis dapat dipanggil paling banyak sekali.
class SimpleClass
{
// Static variable that must be initialized at run time.
static readonly long baseline;
// Static constructor is called at most one time, before any
// instance constructor is invoked or member is accessed.
static SimpleClass()
{
baseline = DateTime.Now.Ticks;
}
}
Ada beberapa tindakan yang merupakan bagian dari inisialisasi statis. Tindakan tersebut terjadi dalam urutan berikut:
- Bidang statis diatur ke 0. Runtime biasanya melakukan inisialisasi ini.
- Penginisialisasi bidang statis berjalan. Penginisialisasi bidang statis pada jenis yang paling terderivasi dijalankan.
- Inisialisasi bidang statis tipe dasar dijalankan. Penginisialisasi medan statis dimulai dari basis langsung dan diteruskan melalui setiap tipe dasar hingga System.Object.
- Setiap konstruktor statis berjalan. Setiap konstruktor statis, mulai dari kelas dasar utama Object.Object hingga setiap kelas dasar melalui jenis tersebut dijalankan. Urutan eksekusi konstruktor statis tidak ditentukan. Namun, semua konstruktor statis dalam hierarki berjalan sebelum instans apa pun dibuat.
Penting
Ada satu pengecualian penting terhadap aturan bahwa konstruktor statis dijalankan sebelum instans apa pun dibuat. Jika penginisialisasi bidang statis membuat instans dari tipe, penginisialisasi tersebut dijalankan (termasuk panggilan apa pun ke konstruktor instans) sebelum konstruktor statis dijalankan. Ini paling umum dalam pola singleton seperti yang ditunjukkan dalam contoh berikut:
public class Singleton
{
// Static field initializer calls instance constructor.
private static Singleton instance = new Singleton();
private Singleton()
{
Console.WriteLine("Executes before static constructor.");
}
static Singleton()
{
Console.WriteLine("Executes after instance constructor.");
}
public static Singleton Instance => instance;
}
Penginisialisasi modul dapat menjadi alternatif untuk konstruktor statis. Untuk informasi selengkapnya, lihat spesifikasi untuk penginisialisasi modul.
Keterangan
Konstruktor statik memiliki sifat-sifat berikut:
- Konstruktor statik tidak menggunakan pengubah akses atau memiliki parameter.
- Kelas atau struktur hanya dapat memiliki satu konstruktor statik.
- Konstruktor statis tidak dapat diwariskan atau kelebihan beban.
- Konstruktor statis tidak dapat dipanggil secara langsung dan hanya dimaksudkan untuk dipanggil oleh CLR (common language runtime). Ini dipanggil secara otomatis.
- Pengguna tidak memiliki kendali kapan konstruktor statik dijalankan dalam program.
- Konstruktor statik dipanggil secara otomatis. Ini menginisialisasi kelas sebelum instans pertama dibuat atau anggota statik apa pun yang dideklarasikan dalam kelas tersebut (bukan kelas dasarnya) direferensikan. Konstruktor statis dijalankan sebelum konstruktor instans. Jika penginisialisasi variabel bidang statis ada di kelas konstruktor statis, mereka berjalan dalam urutan tekstual di mana mereka muncul dalam deklarasi kelas. Penginisialisasi dijalankan segera sebelum konstruktor statis.
- Jika Anda tidak menyediakan konstruktor statik untuk menginisialisasi bidang statik, semua bidang statik diinisialisasi ke nilai defaultnya seperti yang tercantum dalam Nilai default jenis C#.
- Jika konstruktor statis melempar pengecualian, runtime tidak memanggilnya untuk kedua kalinya, dan jenisnya tetap tidak diinisialisasi untuk masa pakai domain aplikasi. Paling umum, pengecualian TypeInitializationException dilemparkan ketika konstruktor statik tidak dapat membuat instans jenis atau untuk pengecualian yang tidak tertangani yang terjadi dalam konstruktor statik. Untuk konstruktor statis yang tidak secara eksplisit ditentukan dalam kode sumber, pemecahan masalah mungkin memerlukan inspeksi kode bahasa perantara (IL).
- Kehadiran konstruktor statik mencegah penambahan atribut jenis BeforeFieldInit. Ini membatasi pengoptimalan waktu proses.
- Bidang yang dideklarasikan sebagai
static readonly
hanya dapat ditetapkan sebagai bagian dari deklarasinya atau dalam konstruktor statis. Ketika konstruktor statis eksplisit tidak diperlukan, inisialisasikan bidang statis pada saat deklarasi daripada melalui konstruktor statis untuk optimisasi waktu proses yang lebih baik. - Runtime memanggil konstruktor statik tidak lebih dari sekali dalam satu domain aplikasi. Panggilan itu dibuat di wilayah terkunci berdasarkan jenis kelas tertentu. Tidak ada mekanisme penguncian tambahan yang diperlukan dalam isi konstruktor statis. Untuk menghindari risiko kebuntuan, jangan hambat utas arus di konstruktor statik dan inisiator. Misalnya, jangan menunggu tugas, utas, handel tunggu, atau peristiwa, jangan memperoleh kunci, dan jangan menjalankan operasi pemblokiran paralel seperti perulangan paralel dan kueri Parallel LINQ.
Catatan
Meskipun tidak dapat diakses secara langsung, kehadiran konstruktor statik eksplisit harus didokumentasikan untuk membantu pemecahan masalah pengecualian inisialisasi.
Penggunaan
- Penggunaan khas konstruktor statik adalah ketika kelas menggunakan file log dan konstruktor digunakan untuk menulis entri ke file ini.
- Konstruktor statik juga berguna saat membuat kelas pembungkus untuk kode tak terkelola, ketika konstruktor dapat memanggil metode
LoadLibrary
. - Konstruktor statis juga merupakan tempat yang nyaman untuk menerapkan pemeriksaan run-time pada parameter jenis yang tidak dapat diperiksa pada waktu kompilasi melalui batasan parameter jenis.
Contoh
Dalam contoh ini, kelas Bus
memiliki konstruktor statik. Ketika instans Bus
pertama dibuat (bus1
), konstruktor statik dipanggil untuk menginisialisasi kelas. Keluaran contoh memverifikasi bahwa konstruktor statik hanya dijalankan satu kali, meskipun dua instance Bus
dibuat, dan dijalankan sebelum konstruktor instance dijalankan.
public class Bus
{
// Static variable used by all Bus instances.
// Represents the time the first bus of the day starts its route.
protected static readonly DateTime globalStartTime;
// Property for the number of each bus.
protected int RouteNumber { get; set; }
// Static constructor to initialize the static variable.
// It is invoked before the first instance constructor is run.
static Bus()
{
globalStartTime = DateTime.Now;
// The following statement produces the first line of output,
// and the line occurs only once.
Console.WriteLine($"Static constructor sets global start time to {globalStartTime.ToLongTimeString()}");
}
// Instance constructor.
public Bus(int routeNum)
{
RouteNumber = routeNum;
Console.WriteLine($"Bus #{RouteNumber} is created.");
}
// Instance method.
public void Drive()
{
TimeSpan elapsedTime = DateTime.Now - globalStartTime;
// For demonstration purposes we treat milliseconds as minutes to simulate
// actual bus times. Do not do this in your actual bus schedule program!
Console.WriteLine($"{this.RouteNumber} is starting its route {elapsedTime.Milliseconds:N2} minutes after global start time {globalStartTime.ToShortTimeString()}.");
}
}
class TestBus
{
static void Main()
{
// The creation of this instance activates the static constructor.
Bus bus1 = new Bus(71);
// Create a second bus.
Bus bus2 = new Bus(72);
// Send bus1 on its way.
bus1.Drive();
// Wait for bus2 to warm up.
System.Threading.Thread.Sleep(25);
// Send bus2 on its way.
bus2.Drive();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Sample output:
Static constructor sets global start time to 3:57:08 PM.
Bus #71 is created.
Bus #72 is created.
71 is starting its route 6.00 minutes after global start time 3:57 PM.
72 is starting its route 31.00 minutes after global start time 3:57 PM.
*/
Spesifikasi bahasa C#
Untuk informasi selengkapnya, lihat bagian Konstruktor statik dari spesifikasi bahasa C#.