Bagikan melalui


Konstruktor Statik (Panduan Pemrograman C#)

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 statik mana pun direferensikan. Konstruktor statis akan 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:

  1. Bidang statis diatur ke 0. Ini biasanya dilakukan oleh runtime.
  2. Penginisialisasi bidang statis berjalan. Penginisialisasi bidang statis dalam eksekusi jenis yang paling turunan.
  3. Penginisialisasi bidang statis jenis dasar berjalan. Penginisialisasi bidang statis dimulai dengan dasar langsung melalui setiap jenis dasar ke System.Object.
  4. Konstruktor statis dasar berjalan. Setiap konstruktor statis, dimulai dengan Object.Object melalui setiap kelas dasar ke kelas dasar langsung.
  5. Konstruktor statis berjalan. Konstruktor statis untuk jenis berjalan.

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 mengambil pengubah akses atau memiliki parameter.
  • Kelas atau struktur hanya dapat memiliki satu konstruktor statik.
  • Konstruktor statik tidak dapat diwariskan atau kelebihan beban.
  • Konstruktor statik tidak dapat dipanggil secara langsung dan hanya dimaksudkan untuk dipanggil oleh runtime bahasa umum (CLR). 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 statik berjalan sebelum konstruktor instans. Jika penginisialisasi variabel bidang statik hadir di kelas konstruktor statik, mereka dijalankan dalam urutan tekstual di mana mereka muncul dalam deklarasi kelas. Penginisialisasi berjalan segera sebelum eksekusi konstruktor statik.
  • 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 statik memberikan pengecualian, runtime tidak memanggilnya untuk kedua kalinya, dan jenisnya akan tetap tidak diinisialisasi selama 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 statik yang tidak didefinisikan secara eksplisit dalam kode sumber, pemecahan masalah mungkin memerlukan pemeriksaan kode bahasa perantara (IL).
  • Kehadiran konstruktor statik mencegah penambahan atribut jenis BeforeFieldInit. Ini membatasi optimasi runtime.
  • Bidang yang dideklarasikan sebagai static readonly hanya dapat ditetapkan sebagai bagian dari deklarasinya atau dalam konstruktor statik. Ketika konstruktor statik eksplisit tidak diperlukan, menginisialisasi bidang statik pada deklarasi daripada melalui konstruktor statik untuk optimasi runtime 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 tubuh konstruktor statik. Untuk menghindari risiko kebuntuan, jangan hambat utas arus di konstruktor statik dan inisiator. Misalnya, jangan menunggu tugas, utas, handel tunggu atau peristiwa, jangan peroleh kunci, dan jangan jalankan pemblokiran operasi paralel seperti perulangan paralel, Parallel.Invoke dan kueri LINQ Paralel.

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 statik juga merupakan tempat yang nyaman untuk menegakkan 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. Output sampel memverifikasi bahwa konstruktor statik hanya berjalan satu kali, meskipun dua instans Bus dibuat, dan berjalan sebelum konstruktor instans berjalan.

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 {0}",
            globalStartTime.ToLongTimeString());
    }

    // Instance constructor.
    public Bus(int routeNum)
    {
        RouteNumber = routeNum;
        Console.WriteLine("Bus #{0} is created.", RouteNumber);
    }

    // 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("{0} is starting its route {1:N2} minutes after global start time {2}.",
                                this.RouteNumber,
                                elapsedTime.Milliseconds,
                                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#.

Lihat juga