Bagikan melalui


Penginisialisasi Modul

Nota

Artikel ini adalah spesifikasi fitur. Spesifikasi berfungsi sebagai dokumen desain untuk fitur tersebut. Ini termasuk perubahan spesifikasi yang diusulkan, bersama dengan informasi yang diperlukan selama desain dan pengembangan fitur. Artikel ini diterbitkan sampai perubahan spesifikasi yang diusulkan diselesaikan dan dimasukkan dalam spesifikasi ECMA saat ini.

Mungkin ada beberapa perbedaan antara spesifikasi fitur dan implementasi yang selesai. Perbedaan tersebut dicatat dalam catatan rapat desain bahasa (LDM) terkait.

Anda dapat mempelajari lebih lanjut tentang proses untuk mengadopsi speklet fitur ke dalam standar bahasa C# dalam artikel tentang spesifikasi .

Edisi Champion: https://github.com/dotnet/csharplang/issues/2608

Ringkasan

Meskipun platform .NET memiliki fitur yang secara langsung mendukung penulisan kode inisialisasi untuk assembly (yang secara teknis adalah modul), fitur ini tidak tersedia dalam C#. Ini adalah skenario yang agak tidak umum, tetapi setelah Anda mengalaminya, solusinya tampak cukup merepotkan. Ada laporan mengenai sejumlah pelanggan (di dalam dan di luar Microsoft) yang menghadapi masalah tersebut, dan tidak diragukan lagi ada lebih banyak kasus yang tidak terdokumentasi.

Motivasi

  • Aktifkan pustaka untuk melakukan inisialisasi satu kali secara cepat ketika diaktifkan, dengan overhead minimal dan tanpa pengguna harus memanggil apa pun secara eksplisit.
  • Salah satu tantangan khusus dari pendekatan konstruktor static saat ini adalah bahwa runtime harus melakukan pemeriksaan tambahan pada penggunaan tipe dengan konstruktor statis, untuk memutuskan apakah konstruktor statis perlu dijalankan atau tidak. Ini menambahkan overhead yang dapat diukur.
  • Mengaktifkan generator sumber untuk menjalankan beberapa logika inisialisasi global tanpa pengguna perlu secara eksplisit memanggil apa pun

Desain terperinci

Metode dapat ditetapkan sebagai penginisialisasi modul dengan mendekorasinya dengan atribut [ModuleInitializer].

using System;
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public sealed class ModuleInitializerAttribute : Attribute { }
}

Atribut dapat digunakan seperti ini:

using System.Runtime.CompilerServices;
class C
{
    [ModuleInitializer]
    internal static void M1()
    {
        // ...
    }
}

Beberapa persyaratan diberlakukan pada metode yang ditargetkan dengan atribut ini:

  1. Metode harus static.
  2. Metode harus tanpa parameter.
  3. Metode harus mengembalikan void.
  4. Metode tidak boleh bersifat generik atau terkandung dalam tipe generik.
  5. Metode harus dapat diakses dari modul yang berisi.
    • Ini berarti tingkat aksesibilitas efektif metode harus internal atau public.
    • Ini juga berarti metode tidak dapat menjadi fungsi lokal.

Ketika satu atau beberapa metode yang valid dengan atribut ini ditemukan dalam kompilasi, pengkompilasi akan memancarkan penginisialisasi modul yang memanggil masing-masing metode yang diatribusikan. Panggilan akan dipancarkan dalam urutan tertentu, tetapi deterministik.

Kekurangan

Mengapa kita tidak melakukan ini?

  • Mungkin alat pihak ketiga yang ada untuk "menyuntikkan" penginisialisasi modul sudah cukup bagi pengguna yang telah meminta fitur ini.

Rapat desain

8 April 2020