Bagikan melalui


Arahan praprosesor C#

Meskipun kompilator tidak memiliki praprosesor terpisah, kompilator memproses arahan yang dijelaskan di bagian ini seolah-olah ada satu. Gunakan arahan ini untuk membantu kompilasi bersyarah. Tidak seperti arahan C dan C ++, Anda tidak dapat menggunakan arahan ini untuk membuat makro. Arahan praprosesor harus menjadi satu-satunya instruksi pada baris.

Referensi bahasa C# mendanai versi bahasa C# yang terbaru dirilis. Ini juga berisi dokumentasi awal untuk fitur dalam pratinjau publik untuk rilis bahasa yang akan datang.

Dokumentasi mengidentifikasi fitur apa pun yang pertama kali diperkenalkan dalam tiga versi terakhir bahasa atau dalam pratinjau publik saat ini.

Tip

Untuk menemukan kapan fitur pertama kali diperkenalkan di C#, lihat artikel tentang riwayat versi bahasa C#.

Aplikasi berbasis file

Aplikasi berbasis file adalah program yang Anda kompilasi dan jalankan dengan menggunakan dotnet run Program.cs (atau file apa pun *.cs ). Pengkompilasi C# mengabaikan arahan praprosesor ini, tetapi sistem build mengurainya untuk menghasilkan output. Arahan ini menghasilkan peringatan ketika ditemui dalam kompilasi berbasis proyek.

Pengkompilasi C# mengabaikan direktif pra-prosesor apa pun yang dimulai dengan #: atau #!.

Direktif #! praproscessor memungkinkan shell Unix untuk langsung menjalankan file C# dengan menggunakan dotnet run. Contohnya:

#!/usr/bin/env dotnet run
Console.WriteLine("Hello");

Cuplikan kode sebelumnya menginformasikan shell Unix untuk menjalankan file dengan menggunakan dotnet run. Perintah /usr/bin/env menemukan dotnet executable di PATH Anda, membuat pendekatan ini portabel di berbagai distribusi Unix dan macOS. Baris #! harus menjadi baris pertama dalam file, dan token berikut adalah program yang akan dijalankan. Anda perlu mengaktifkan izin jalankan (x) pada file C# untuk fitur tersebut.

Arahan #: yang digunakan dalam aplikasi berbasis file dijelaskan dalam referensi aplikasi berbasis file.

Alat lain dapat menambahkan token baru setelah #: konvensi.

Konteks yang dapat diubah ke null

Direktif praprosesor #nullable menetapkan anotasi dan bendera peringatan dalam konteks nullable . Arahan ini mengontrol apakah anotasi yang dapat diubah ke null memiliki efek, dan apakah peringatan nullability diberikan. Setiap bendera dinonaktifkan atau diaktifkan.

Anda dapat menentukan kedua konteks di tingkat proyek (di luar kode sumber C#) dengan menambahkan Nullable elemen ke PropertyGroup elemen . Direktif #nullable mengontrol anotasi dan bendera peringatan dan lebih diutamakan daripada pengaturan tingkat proyek. Direktif mengatur bendera yang dikendalikannya sampai direktif lain menimpanya, atau hingga akhir file sumber.

Efek dari arahan adalah sebagai berikut:

  • #nullable disable: Mengatur agar konteks nullable dinonaktifkan.
  • #nullable enable: Mengatur konteks nullable diaktifkan.
  • #nullable restore: Memulihkan konteks nullable ke pengaturan proyek.
  • #nullable disable annotations: Mengatur bendera anotasi dalam konteks nullable ke dinonaktifkan.
  • #nullable enable annotations: Mengatur bendera anotasi dalam konteks nullable ke diaktifkan.
  • #nullable restore annotations: Memulihkan bendera anotasi dalam konteks nullable ke pengaturan proyek.
  • #nullable disable warnings: Mengatur bendera peringatan dalam konteks null ke dinonaktifkan.
  • #nullable enable warnings: Mengatur bendera peringatan dalam konteks nullable ke diaktifkan.
  • #nullable restore warnings: Mengembalikan tanda peringatan dalam konteks nullable ke pengaturan proyek.

Kompilasi kondisional

Gunakan empat arahan pra-prosesor untuk mengontrol kompilasi kondisional:

  • #if: Memulai kompilasi bersyarah. Pengkompilasi mengkompilasi kode hanya jika simbol yang ditentukan ditentukan.
  • #elif: Menutup kompilasi kondisional sebelumnya dan membuka kompilasi kondisional baru berdasarkan apakah simbol yang ditetapkan telah ditentukan.
  • #else: Menutup kompilasi kondisional sebelumnya dan membuka kompilasi kondisional baru berdasarkan apakah simbol yang ditetapkan sebelumnya belum ditentukan.
  • #endif: Menutup kompilasi kondisional sebelumnya.

Sistem build juga mengetahui simbol praprosesor yang telah ditentukan sebelumnya yang mewakili kerangka kerja target yang berbeda dalam proyek bergaya SDK. Simbol tersebut berguna saat membuat aplikasi yang dapat menargetkan lebih dari satu versi .NET.

Kerangka Kerja Target Simbol Simbol tambahan
(tersedia dalam .NET 5+ SDK)
Simbol platform (hanya tersedia
saat Anda menentukan TFM khusus OS)
.NET Framework NETFRAMEWORK, , NET481, NET48NET472, NET471, NET47, NET462, NET461, NET46, NET452, NET451, NET45, , NET40, NET35NET20 NET48_OR_GREATER, , NET472_OR_GREATERNET471_OR_GREATER, NET47_OR_GREATER, NET462_OR_GREATER, NET461_OR_GREATER, NET46_OR_GREATER, NET452_OR_GREATER, NET451_OR_GREATER, NET45_OR_GREATER, , NET40_OR_GREATER, , NET35_OR_GREATERNET20_OR_GREATER
.NET Standar NETSTANDARD, , NETSTANDARD2_1NETSTANDARD2_0, NETSTANDARD1_6, NETSTANDARD1_5, NETSTANDARD1_4, NETSTANDARD1_3, NETSTANDARD1_2, , NETSTANDARD1_1,NETSTANDARD1_0 NETSTANDARD2_1_OR_GREATER, , NETSTANDARD2_0_OR_GREATERNETSTANDARD1_6_OR_GREATER, NETSTANDARD1_5_OR_GREATER, NETSTANDARD1_4_OR_GREATER, NETSTANDARD1_3_OR_GREATER, NETSTANDARD1_2_OR_GREATER, , NETSTANDARD1_1_OR_GREATER,NETSTANDARD1_0_OR_GREATER
.NET 5+ (dan .NET Core) NET, , NET10_0, NET9_0NET8_0, NET7_0, NET6_0, NET5_0, NETCOREAPP, NETCOREAPP3_1, NETCOREAPP3_0, NETCOREAPP2_2, NETCOREAPP2_1, , NETCOREAPP2_0, NETCOREAPP1_1NETCOREAPP1_0 NET10_0_OR_GREATER, , NET9_0_OR_GREATERNET8_0_OR_GREATER, NET7_0_OR_GREATER, NET6_0_OR_GREATER, NET5_0_OR_GREATER, NETCOREAPP3_1_OR_GREATER, NETCOREAPP3_0_OR_GREATER, NETCOREAPP2_2_OR_GREATER, NETCOREAPP2_1_OR_GREATER, , NETCOREAPP2_0_OR_GREATER, , NETCOREAPP1_1_OR_GREATERNETCOREAPP1_0_OR_GREATER ANDROID, , BROWSERIOS, MACCATALYST, MACOS, TVOS, , WINDOWS,
[OS][version] (misalnya IOS15_1),
[OS][version]_OR_GREATER (misalnya IOS15_1_OR_GREATER)

Catatan

  • Simbol tanpa versi ditentukan terlepas dari versi yang Anda targetkan.
  • Simbol khusus versi hanya ditentukan untuk versi yang Anda targetkan.
  • Simbol <framework>_OR_GREATER ditentukan untuk versi yang Anda targetkan dan semua versi sebelumnya. Misalnya, jika Anda menargetkan .NET Framework 2.0, simbol berikut ditentukan: NET20, NET20_OR_GREATER, NET11_OR_GREATER, dan NET10_OR_GREATER.
  • Simbol NETSTANDARD<x>_<y>_OR_GREATER hanya didefinisikan untuk target .NET Standard, dan bukan untuk target yang mengimplementasikan .NET Standard, seperti .NET Core dan .NET Framework.
  • Ini berbeda dari moniker kerangka kerja target (TFM) yang digunakan oleh properti MSBuild TargetFramework dan NuGet.

Catatan

Untuk proyek tradisional bergaya non-SDK, Anda harus mengonfigurasi simbol kompilasi kondisional secara manual untuk kerangka kerja target yang berbeda di Visual Studio melalui halaman properti proyek.

Simbol lain yang telah ditentukan sebelumnya termasuk konstanta DEBUG dan TRACE. Gunakan #define untuk mengambil alih nilai yang ditetapkan untuk proyek. Simbol DEBUG , misalnya, secara otomatis diatur tergantung pada properti konfigurasi build Anda (mode "Debug" atau "Rilis").

Pengkompilasi C# mengkompilasi kode antara #if direktif dan #endif direktif hanya jika simbol yang ditentukan ditentukan, atau tidak ditentukan ketika ! operator tidak digunakan. Tidak seperti C dan C++, Anda tidak dapat menetapkan nilai numerik ke simbol. Pernyataan #if dalam C# adalah Boolean dan hanya menguji apakah simbol didefinisikan atau tidak. Misalnya, kode berikut dikompilasi saat DEBUG ditentukan:

#if DEBUG
    Console.WriteLine("Debug version");
#endif

Kode berikut dikompilasi ketika MYTESTtidak ditentukan:

#if !MYTEST
    Console.WriteLine("MYTEST is not defined");
#endif

Gunakan operator (kesetaraan==) dan != (ketidaksetaraan) untuk bool menguji nilai true atau false. true berarti simbol telah ditentukan. Pernyataan #if DEBUG ini memiliki arti yang sama dengan #if (DEBUG == true). && Gunakan operator (dan),|| (atau), dan ! (bukan) untuk mengevaluasi apakah beberapa simbol ditentukan. Anda juga dapat mengelompokkan simbol dan operator dengan tanda kurung.

Contoh berikut menunjukkan arahan rumit yang memungkinkan kode Anda untuk memanfaatkan fitur .NET yang lebih baru sambil tetap kompatibel ke belakang. Misalnya, bayangkan Anda menggunakan paket NuGet dalam kode Anda, tetapi paket hanya mendukung .NET 6 dan yang lebih baru, serta .NET Standard 2.0 dan yang lebih baru:

#if (NET6_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER)
    Console.WriteLine("Using .NET 6+ or .NET Standard 2+ code.");
#else
    Console.WriteLine("Using older code that doesn't support the above .NET versions.");
#endif

#if, bersama dengan arahan #else, #elif, #endif, #define, dan #undef, memungkinkan Anda menyertakan atau mengecualikan kode berdasarkan keberadaan satu atau beberapa simbol. Kompilasi kondisional dapat berguna saat mengompilasi kode untuk debug build atau saat mengompilasi untuk konfigurasi tertentu.

#elif memungkinkan Anda membuat arahan kondisional majemuk. Kompilator mengevaluasi #elif ekspresi jika ekspresi sebelumnya #if atau ekspresi direktif opsional #elif dan opsional tidak dievaluasi ke true. Jika ekspresi #elif mengevaluasi ke true, pengompilasi mengevaluasi semua kode antara #elif dan arahan kondisional berikutnya. Contohnya:

#define VC7
//...
#if DEBUG
    Console.WriteLine("Debug build");
#elif VC7
    Console.WriteLine("Visual Studio 7");
#endif

#else memungkinkan Anda membuat arahan kondisional majemuk. Jika tidak ada ekspresi dalam arahan #if sebelumnya atau (opsional) #elif yang dievaluasi ke true, pengkompilasi mengevaluasi semua kode antara #else dan berikutnya #endif. #endif harus menjadi arahan praprosesor berikutnya setelah #else.

#endif menentukan akhir dari arahan kondisional, yang dimulai dengan arahan #if.

Contoh berikut menunjukkan cara menentukan MYTEST simbol dalam file lalu menguji nilai MYTEST simbol dan DEBUG . Output dari contoh ini tergantung pada apakah Anda membangun proyek dalam mode konfigurasi Debug atau Rilis .

#define MYTEST
using System;
public class MyClass
{
    static void Main()
    {
#if (DEBUG && !MYTEST)
        Console.WriteLine("DEBUG is defined");
#elif (!DEBUG && MYTEST)
        Console.WriteLine("MYTEST is defined");
#elif (DEBUG && MYTEST)
        Console.WriteLine("DEBUG and MYTEST are defined");
#else
        Console.WriteLine("DEBUG and MYTEST are not defined");
#endif
    }
}

Contoh berikut menunjukkan cara menguji kerangka kerja target yang berbeda sehingga Anda dapat menggunakan API yang lebih baru jika memungkinkan:

public class MyClass
{
    static void Main()
    {
#if NET40
        WebClient _client = new WebClient();
#else
        HttpClient _client = new HttpClient();
#endif
    }
    //...
}

Mendefinisikan simbol

Gunakan dua arahan praprosesor berikut untuk menentukan atau membatalkan definisi simbol untuk kompilasi bersyariah:

  • #define: Tentukan simbol.
  • #undef: Batalkan penentuan simbol.

Gunakan #define untuk menentukan simbol. Saat Anda menggunakan simbol sebagai ekspresi yang diteruskan ke direktif #if, ekspresi akan bernilai true, seperti yang diperlihatkan dalam contoh berikut.

#define VERBOSE

#if VERBOSE
   Console.WriteLine("Verbose output version");
#endif

Catatan

Di C#, konstanta primitif harus ditentukan dengan menggunakan const kata kunci. const Deklarasi membuat static anggota yang tidak dapat dimodifikasi saat runtime. Direktif #define tidak dapat digunakan untuk mendeklarasikan nilai konstan seperti yang biasanya dilakukan di C dan C++. Jika Anda memiliki beberapa konstanta seperti itu, pertimbangkan untuk membuat kelas "Konstanta" terpisah untuk menahannya.

Gunakan simbol untuk menentukan kondisi kompilasi. Uji simbol dengan menggunakan atau #if#elif. Anda juga dapat menggunakan ConditionalAttribute untuk melakukan kompilasi kondisional. Anda dapat menentukan simbol, tetapi Anda tidak dapat menetapkan nilai ke simbol. Arahan #define harus muncul dalam file sebelum Anda menggunakan instruksi apa pun yang juga bukan arahan praprosesor. Anda juga dapat menentukan simbol dengan menggunakan opsi pengkompilasi DefineConstants . Tidak menentukan simbol dengan menggunakan #undef.

Mendefinisikan wilayah

Tentukan wilayah kode yang dapat Anda ciutkan dalam kerangka dengan menggunakan dua arahan praprosesor berikut:

  • #region: Mulai wilayah.
  • #endregion: Mengakhiri wilayah.

#region memungkinkan Anda menentukan blok kode yang dapat Anda perluas atau ciutkan saat menggunakan fitur kerangka editor kode. Dalam file kode yang lebih panjang, lebih mudah untuk menciutkan atau menyembunyikan satu atau beberapa wilayah sehingga Anda dapat fokus pada bagian file yang sedang Anda kerjakan. Contoh berikut menunjukkan cara menentukan wilayah:

#region MyClass definition
public class MyClass
{
    static void Main()
    {
    }
}
#endregion

Blok #region harus dihentikan dengan arahan #endregion. Blok #region tidak dapat tumpang tindih dengan blok #if. Namun, blok #region dapat disarangkan dalam blok #if, dan blok #if dapat disarangkan dalam blok #region.

Informasi kesalahan dan peringatan

Anda dapat menggunakan arahan berikut untuk menghasilkan kesalahan dan peringatan kompilator yang ditentukan pengguna, dan informasi garis kontrol:

  • #error: Hasilkan kesalahan pengompilasi dengan pesan tertentu.
  • #warning: Hasilkan peringatan pengompilasi, dengan pesan spesifik.
  • #line: Ubah nomor baris yang dicetak dengan pesan pengompilasi.

Gunakan #error untuk menghasilkan kesalahan yang ditentukan pengguna CS1029 dari lokasi tertentu dalam kode Anda. Contohnya:

#error Deprecated code in this method.

Catatan

Pengompilasi memperlakukan #error version dengan cara khusus dan melaporkan kesalahan pengompilasi, CS8304, dengan pesan yang berisi pengompilasi dan versi bahasa yang digunakan.

Gunakan #warning untuk menghasilkan peringatan kompilator tingkat satu CS1030 dari lokasi tertentu dalam kode Anda. Contohnya:

#warning Deprecated code in this method.

Gunakan #line untuk mengubah penomoran baris pengkompilasi dan (opsional) output nama file untuk kesalahan dan peringatan.

Contoh berikut menunjukkan cara melaporkan dua peringatan yang terkait dengan nomor baris. Direktif #line 200 memaksa nomor baris berikutnya menjadi 200 (meskipun defaultnya adalah #6), dan sampai arahan berikutnya #line , nama file dilaporkan sebagai "Spesial." Direktif #line default mengembalikan penomoran baris ke penomoran defaultnya, yang menghitung baris yang dijumlahkan ulang oleh arahan sebelumnya.

class MainClass
{
    static void Main()
    {
#line 200 "Special"
        int i;
        int j;
#line default
        char c;
        float f;
#line hidden // numbering not affected
        string s;
        double d;
    }
}

Kompilasi menghasilkan output berikut:

Special(200,13): warning CS0168: The variable 'i' is declared but never used
Special(201,13): warning CS0168: The variable 'j' is declared but never used
MainClass.cs(9,14): warning CS0168: The variable 'c' is declared but never used
MainClass.cs(10,15): warning CS0168: The variable 'f' is declared but never used
MainClass.cs(12,16): warning CS0168: The variable 's' is declared but never used
MainClass.cs(13,16): warning CS0168: The variable 'd' is declared but never used

Arahan #line dapat digunakan dalam langkah otomatis dan menengah dalam proses build. Misalnya, jika Anda menghapus baris dari file kode sumber asli, tetapi Anda masih ingin pengkompilasi menghasilkan output berdasarkan penomoran baris asli dalam file, Anda dapat menghapus baris lalu mensimulasikan penomoran baris asli dengan menggunakan #line.

Direktif #line hidden menyembunyikan baris berturut-turut dari debugger, sehingga ketika pengembang melangkah melalui kode, baris apa pun antara direktif dan #line hidden berikutnya #line (dengan asumsi bahwa itu bukan arahan lain #line hidden ) dilangkahi. Opsi ini juga dapat digunakan untuk memungkinkan ASP.NET membedakan antara kode yang ditentukan pengguna dan yang dibuat mesin. Meskipun ASP.NET adalah konsumen utama fitur ini, kemungkinan lebih banyak generator sumber yang memanfaatkannya.

Arahan #line hidden tidak memengaruhi nama file atau nomor baris dalam pelaporan kesalahan. Artinya, jika pengkompilasi menemukan kesalahan dalam blok tersembunyi, pengkompilasi melaporkan nama file saat ini dan nomor baris kesalahan.

Arahan n#line filename menentukan nama file yang ingin Anda munculkan dalam output pengompilasi. Secara default, nama sebenarnya dari file kode sumber digunakan. Nama file harus dalam tanda kutip ganda ("") dan harus mengikuti nomor baris.

Anda dapat menggunakan bentuk baru direktif #line:

#line (1, 1) - (5, 60) 10 "partial-class.cs"
/*34567*/int b = 0;

Komponen dari bentuk ini adalah:

  • (1, 1): Baris awal dan kolom untuk karakter pertama pada baris setelah arahan. Dalam contoh ini, baris berikutnya dilaporkan sebagai baris 1, kolom 1.
  • (5, 60): Baris akhir dan kolom untuk wilayah yang ditandai.
  • 10: Offset kolom agar arahan #line berlaku. Dalam contoh ini, kolom ke-10 dilaporkan sebagai kolom satu. Deklarasi int b = 0; dimulai pada kolom tersebut. Bidang ini bersifat opsional. Jika dihilangkan, arahan berlaku pada kolom pertama.
  • "partial-class.cs": Nama file output.

Contoh sebelumnya menghasilkan peringatan berikut:

partial-class.cs(1,5,1,6): warning CS0219: The variable 'b' is assigned but its value is never used

Setelah dipetakan ulang, variabel b berada di baris pertama, pada karakter enam, dari file partial-class.cs.

Bahasa khusus domain (DSL) biasanya menggunakan format ini untuk memberikan pemetaan yang lebih baik dari file sumber ke output C# yang dihasilkan. Penggunaan paling umum dari direktif #line yang diperluas ini adalah untuk memulihkan peringatan atau kesalahan yang muncul dalam file yang dihasilkan ke sumber asli. Misalnya, pertimbangkan halaman pisau cukur ini:

@page "/"
Time: @DateTime.NowAndThen

Properti DateTime.Now salah ditik sebagai DateTime.NowAndThen. C# yang dihasilkan untuk cuplikan pisau cukur ini terlihat seperti berikut ini, di page.g.cs:

  _builder.Add("Time: ");
#line (2, 6) - (2, 27) 15 "page.razor"
  _builder.Add(DateTime.NowAndThen);

Output kompilator untuk cuplikan sebelumnya adalah:

page.razor(2, 2, 2, 27)error CS0117: 'DateTime' does not contain a definition for 'NowAndThen'

Baris 2, kolom 6 dalam page.razor adalah tempat teks @DateTime.NowAndThen dimulai, dicatat oleh (2, 6) dalam direktif. Rentang @DateTime.NowAndThen itu berakhir pada baris 2, kolom 27, dicatat oleh (2, 27) dalam petunjuk. Teks untuk DateTime.NowAndThen dimulai di kolom 15 dari page.g.cs, dicatat oleh 15 pada instruksi. Pengkompilasi melaporkan kesalahan di lokasinya di page.razor. Pengembang dapat menavigasi langsung ke kesalahan dalam kode sumber mereka, bukan sumber yang dihasilkan.

Untuk melihat contoh lainnya dari format ini, lihat spesifikasi fitur di bagian pada contoh.

Pragma

Pengkompilasi menggunakan #pragma untuk mendapatkan instruksi khusus untuk mengkompilasi file tempatnya muncul. Kompilator harus mendukung pragma yang Anda gunakan. Dengan kata lain, Anda tidak dapat menggunakan #pragma untuk membuat instruksi prapemrosesan kustom.

#pragma pragma-name pragma-arguments

pragma-name adalah nama pragma yang diakui. pragma-arguments adalah argumen khusus pragma.

peringatan #pragma

#pragma warning dapat mengaktifkan atau menonaktifkan peringatan tertentu. #pragma warning disable format dan #pragma warning enable format mengontrol cara Visual Studio memformat blok kode.

#pragma warning disable warning-list
#pragma warning restore warning-list

warning-list adalah daftar angka peringatan yang dipisahkan koma, seperti 414, CS3021. Prefiks "CS" bersifat opsional. Saat Anda tidak menentukan nomor peringatan, disable nonaktifkan semua peringatan dan restore aktifkan semua peringatan.

Catatan

Untuk menemukan nomor peringatan di Visual Studio, bangun proyek Anda lalu cari nomor peringatan di jendela Output.

Efek disable mulai pada baris berikutnya dari file sumber. Peringatan dipulihkan pada baris setelah restore. Jika tidak restore ada dalam file, peringatan akan dipulihkan ke status defaultnya pada baris pertama file nanti dalam kompilasi yang sama.

// pragma_warning.cs
using System;

#pragma warning disable 414, CS3021
[CLSCompliant(false)]
public class C
{
    int i = 1;
    static void Main()
    {
    }
}
#pragma warning restore CS3021
[CLSCompliant(false)]  // CS3021
public class D
{
    int i = 1;
    public static void F()
    {
    }
}

Bentuk lain dari pragma warning menonaktifkan atau memulihkan perintah pemformatan Visual Studio dalam blok kode:

#pragma warning disable format
#pragma warning restore format

Perintah format Visual Studio tidak mengubah teks dalam blok kode tempat disable format berlaku. Perintah format, seperti Ctrl+K, Ctrl+D, jangan ubah wilayah kode tersebut. Pragma ini memberi Anda kontrol yang baik atas presentasi visual kode Anda.

checksum #pragma

Menghasilkan checksum untuk file sumber untuk membantu penelusuran kesalahan ASP.NET halaman.

#pragma checksum "filename" "{guid}" "checksum bytes"

Direktif menggunakan "filename" sebagai nama file untuk memantau perubahan atau pembaruan, "{guid}" sebagai Pengidentifikasi Unik Global (GUID) untuk algoritma hash, dan "checksum_bytes" sebagai string digit heksadesimal yang mewakili byte checksum. Anda harus menyediakan jumlah digit heksadesimal yang merata. Jumlah digit ganjil menghasilkan peringatan waktu kompilasi, dan arahan diabaikan.

Debugger Visual Studio menggunakan checksum untuk memastikan bahwa ia selalu menemukan sumber yang tepat. Pengompilasi menghitung checksum untuk file sumber, kemudian memancarkan output ke file database program (PDB). Debugger menggunakan PDB untuk membandingkan dengan checksum yang dihitung untuk file sumber.

Solusi ini tidak berfungsi untuk proyek ASP.NET, karena checksum yang dihitung adalah untuk file sumber yang dihasilkan, bukan file .aspx. Untuk mengatasi masalah ini, #pragma checksum memberikan dukungan checksum untuk halaman ASP.NET.

Saat Anda membuat proyek ASP.NET di Visual C#, file sumber yang dihasilkan berisi checksum untuk file .aspx, asal sumber dihasilkan. Pengompilasi kemudian menulis informasi ini ke dalam file PDB.

Jika pengompilasi tidak menemukan arahan #pragma checksum dalam file, pengompilasi menghitung checksum dan menulis nilainya ke file PDB.

class TestClass
{
    static int Main()
    {
        #pragma checksum "file.cs" "{406EA660-64CF-4C82-B6F0-42D48172A799}" "ab007f1d23d9" // New checksum
    }
}