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.
Meskipun pengompilasi tidak memiliki praprosesor terpisah, arahan yang dijelaskan dalam bagian ini diproses seolah-olah ada satu. Anda menggunakannya untuk membantu dalam kompilasi kondisional. Tidak seperti arahan C dan C ++, Anda tidak dapat menggunakan arahan ini untuk membuat makro. Arahan praprosesor harus menjadi satu-satunya instruksi pada baris.
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.
Kedua konteks dapat ditentukan pada tingkat proyek (di luar kode sumber C#) yang 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
Anda menggunakan empat arahab praprosesor untuk mengontrol kompilasi kondisional:
-
#if
: Membuka kompilasi kondisional, di mana kode dikompilasi hanya jika simbol yang ditetapkan telah 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 , NET48 NET472 , NET471 , NET47 , NET462 , NET461 , NET46 , NET452 , NET451 , NET45 , , NET40 , NET35 NET20 |
NET48_OR_GREATER , , NET472_OR_GREATER NET471_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_GREATER NET20_OR_GREATER |
|
.NET Standar |
NETSTANDARD , , NETSTANDARD2_1 NETSTANDARD2_0 , NETSTANDARD1_6 , NETSTANDARD1_5 , NETSTANDARD1_4 , NETSTANDARD1_3 , NETSTANDARD1_2 , , NETSTANDARD1_1 ,NETSTANDARD1_0 |
NETSTANDARD2_1_OR_GREATER , , NETSTANDARD2_0_OR_GREATER NETSTANDARD1_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 , , NET9_0 NET8_0 , NET7_0 , NET6_0 , NET5_0 , NETCOREAPP , NETCOREAPP3_1 , NETCOREAPP3_0 , NETCOREAPP2_2 , NETCOREAPP2_1 , NETCOREAPP2_0 , , , NETCOREAPP1_1 NETCOREAPP1_0 |
NET8_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_GREATER NETCOREAPP1_0_OR_GREATER |
ANDROID , , BROWSER IOS , 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
, danNET10_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
. Anda dapat menimpa nilai yang ditetapkan untuk proyek menggunakan #define
. 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++, nilai numerik ke simbol tidak dapat ditetapkan. 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 MYTEST
tidak ditentukan:
#if !MYTEST
Console.WriteLine("MYTEST is not defined");
#endif
Anda dapat menggunakan operator ==
(kesetaraan) dan !=
(ketidaksetaraan) untuk menguji nilai bool
true
atau false
.
true
berarti simbol telah ditentukan. Pernyataan #if DEBUG
ini memiliki arti yang sama dengan #if (DEBUG == true)
. Anda dapat menggunakan 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. Ekspresi #elif
dievaluasi jika baik ekspresi direktif #if
sebelumnya maupun ekspresi direktif opsional #elif
sebelumnya tidak dievaluasi menjadi 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, sehingga, jika tidak ada ekspresi dalam arahan #if
sebelumnya atau #elif
(opsional) yang dievaluasi ke true
, pengompilasi akan mengevaluasi semua kode antara #else
dan #endif
berikutnya.
#endif
(#endif) harus menjadi arahan praprosesor berikutnya setelah #else
.
#endif
menentukan akhir dari arahan kondisional, yang dimulai dengan arahan #if
.
Contoh berikut menunjukkan kepada Anda cara menentukan simbol MYTEST
pada file lalu menguji nilai simbol MYTEST
dan DEBUG
. Output dari contoh ini tergantung pada apakah Anda membangun proyek pada 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 kepada Anda 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
Anda menggunakan dua arahan praprosesor berikut untuk menentukan atau membatalkan penentuan simbol untuk kompilasi kondisional:
-
#define
: Tentukan simbol. -
#undef
: Batalkan penentuan simbol.
Anda menggunakan #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 didefinisikan 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.
Simbol dapat digunakan untuk menentukan kondisi untuk kompilasi. Anda dapat menguji simbol dengan #if
atau #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 opsi pengompilasi DefineConstants. Anda dapat membatalkan penentuan simbol dengan #undef
.
Mendefinisikan wilayah
Anda dapat menentukan wilayah kode yang dapat diciutkan dalam kerangka 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 menginstruksikan pengompilasi untuk menghasilkan kesalahan dan peringatan pengompilasi yang ditentukan pengguna, dan mengontrol informasi baris menggunakan arahan berikut:
-
#error
: Hasilkan kesalahan pengompilasi dengan pesan tertentu. -
#warning
: Hasilkan peringatan pengompilasi, dengan pesan spesifik. -
#line
: Ubah nomor baris yang dicetak dengan pesan pengompilasi.
#error
memungkinkan Anda 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.
#warning
memungkinkan Anda menghasilkan peringatan pengompilasi tingkat satu CS1030 dari lokasi tertentu dalam kode Anda. Contohnya:
#warning Deprecated code in this method.
#line
memungkinkan Anda memodifikasi penomoran baris pengompilasi 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 direktif #line
berikutnya, nama file akan dilaporkan sebagai "Spesial." Direktif #line default
mengembalikan penomoran baris ke penomoran defaultnya, yang menghitung baris yang dinomorl ulang oleh direktif 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 baris dihapus dari file kode sumber asli, tetapi Anda masih ingin pengompilasi menghasilkan output berdasarkan penomoran baris asli dalam file, Anda dapat menghapus baris dan kemudian menyimulasikan penomoran baris asli dengan #line
.
Arahan #line hidden
menyembunyikan baris berturut-turut dari debugger, sehingga ketika pengembang menelusuri kode, baris apa pun antara #line hidden
dan arahan #line
berikutnya (dengan asumsi bahwa itu bukan arahan #line hidden
lain) akan 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 akan 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 akan dilaporkan sebagai kolom satu. Deklarasiint 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 akan menghasilkan peringatan berikut:
partial-class.cs(1,5,1,6): warning CS0219: The variable 'b' is assigned but its value is never used
Setelah remapping, 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 di ketik 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
#pragma
memberikan instruksi khusus kepada pengompilasi untuk kompilasi file tempat file muncul. Kompilator harus mendukung pragma yang Anda gunakan. Dengan kata lain, Anda tidak dapat menggunakan #pragma
untuk membuat instruksi prapemrosesan kustom.
-
#pragma warning
: Aktifkan atau nonaktifkan peringatan. -
#pragma checksum
: Hasilkan checksum.
#pragma pragma-name pragma-arguments
Di mana pragma-name
adalah nama pragma yang diakui dan pragma-arguments
merupakan 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
Di mana warning-list
adalah daftar nomor peringatan yang dipisahkan koma, seperti 414, CS3021
. Prefiks "CS" bersifat opsional. Ketika tidak ada nomor peringatan yang ditentukan, disable
menonaktifkan semua peringatan dan restore
mengaktifkan 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 restore
tidak ada dalam file, peringatan dipulihkan ke status defaultnya pada baris pertama file apa pun setelahnya 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 debugging halaman ASP.NET.
#pragma checksum "filename" "{guid}" "checksum bytes"
Di mana "filename"
adalah nama file yang memerlukan pemantauan untuk perubahan atau pembaruan, "{guid}"
adalah Pengidentifikasi Unik Global (GUID) untuk algoritma hash, dan "checksum_bytes"
merupakan string digit heksadesimal yang mewakili byte checksum. Harus ada jumlah digit heksadesimal yang genap. 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 kemudian 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
}
}