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.
Kata safe kunci kontekstual menandai deklarasi karena tidak memerlukan unsafe konteks di situs penggunaannya di bawah model keamanan memori yang diperbarui. Pengubah safe adalah mitra untuk unsafe. Konteks yang tidak aman tidak diperlukan untuk penelepon safe deklarasi, sambil unsafe menyebarluaskan kewajiban untuk mengaudit keamanan kepada pemanggil.
Menggunakan kata kunci itu safe sendiri memerlukan AllowUnsafeBlocks opsi pengkompilasi (-unsafe), meskipun penelepon tidak memerlukan unsafe konteks. Deklarasi biasa aman secara default, jadi hilangkan safe jika tidak diperlukan untuk menghindari kompilasi yang tidak perlu.
Important
Kata safe kunci adalah bagian dari model keamanan memori yang diperbarui, fitur pratinjau di C# 15 dan .NET 11. Atur LangVersion ke preview untuk mengaktifkan sintaks. Untuk juga menerapkan aturan yang diperbarui, termasuk eksplisit safe atau unsafe pilihan dan memerlukan kewajiban penelepon yang tidak aman, aktifkan updated-memory-safety-rules fitur kompilator. Untuk detail aktivasi, lihat Mengaktifkan aturan keamanan memori yang diperbarui. Untuk desain lengkapnya, lihat spesifikasi fitur keamanan memori.
Deklarasi yang diizinkan dan diperlukan
Anda dapat menerapkan safe ke deklarasi yang mengizinkan pengubah yang memerlukan tidak aman, termasuk metode, konstruktor, properti, dan bidang. Untuk deklarasi biasa, pengubah dapat membuat kontrak yang dimaksudkan eksplisit, termasuk dalam kode yang dihasilkan sumber. Ini tidak terbatas pada extern anggota dan bidang tata letak.
Deklarasi tertentu memerlukan pilihan safe eksplisit atau unsafe ketika aturan yang diperbarui diaktifkan. Bagian berikut ini menjelaskan extern anggota dan bidang tata letak eksplisit atau diperluas.
Tidak seperti unsafe, safe tidak menetapkan konteks leksikal. Ini tidak membuat operasi yang tidak aman dalam tubuh anggota aman atau membatalkan konteks yang tidak aman. Anda tidak dapat menggabungkan safe pengubah dan unsafe pada deklarasi yang sama; melakukannya menghasilkan CS9388.
Dalam kompilator yang lebih baru, safe deklarasi juga memerlukan AllowUnsafeBlocks, meskipun penelepon tidak memerlukan konteks yang tidak aman. Atur <AllowUnsafeBlocks>true</AllowUnsafeBlocks> dalam file proyek Anda untuk mengatasi CS9401. Pemeriksaan pengubah ini tidak bergantung pada keikutsertaan penegakan aturan yang diperbarui. Roslyn men dokumennya seperti yang diperkenalkan dalam Visual Studio 2026 versi 18.13, setelah .NET 11.0.100; kompilator RC2 .NET 11 tidak memberlakukan persyaratan ini untuk safe. Untuk batas kompilator dan perbedaan dari CS0227 pada blok yang tidak aman, lihat Persyaratan konteks yang tidak aman.
Anggota ekstern
Anggota extern memanggil kode asli, sehingga pengkompilasi tidak dapat mengklasifikasikan keamanannya. Di bawah model yang diperbarui, Anda menandai setiap extern deklarasi, termasuk LibraryImport metode parsial, baik safe atau unsafe:
// Syntax requires LangVersion preview; enforcement requires the updated-memory-safety-rules compiler feature.
[LibraryImport("libc")]
internal static safe partial int getpid();
[LibraryImport("libc", StringMarshalling = StringMarshalling.Utf8)]
internal static unsafe partial nint strlen(byte* str);
getpid tidak mengambil parameter dan mengembalikan primitif, sehingga penulis membuktikan bahwa panggilan aman, dan penelepon menggunakannya tanpa unsafe konteks.
strlen mengambil pointer mentah yang dereferensi kode asli, sehingga deklarasinya adalah unsafe dan menyebarluaskan kewajiban kepada pemanggilnya. Dengan aturan yang diperbarui diaktifkan, menghilangkan kedua pengubah adalah kesalahan.
Bidang tata letak eksplisit atau diperluas
Dalam jenis dengan [StructLayout(LayoutKind.Explicit)] atau [ExtendedLayout], pengkompilasi tidak dapat mengklasifikasikan keamanan setiap bidang instans sendiri. Anda menandai setiap bidang tersebut baik safe atau unsafe:
// Syntax requires LangVersion preview; enforcement requires the updated-memory-safety-rules compiler feature.
[StructLayout(LayoutKind.Explicit)]
internal struct Union
{
[FieldOffset(0)]
internal safe int AsInt;
[FieldOffset(0)]
internal safe float AsFloat;
}
Bidang yang menyimpan pointer asli, atau yang jenisnya membawa invarian yang tidak dapat diekspresikan oleh sistem jenis, adalah unsafe. Bidang yang jenisnya sepenuhnya dijelaskan oleh sistem jenis adalah safe. Aturan yang sama berlaku untuk bidang tata letak eksplisit dan bidang tata letak yang diperluas. Seperti halnya extern anggota, menghilangkan kedua pengubah adalah kesalahan ketika aturan yang diperbarui diaktifkan.
Terapkan pengubah yang sama ke bidang instans dalam jenis dengan nonzero StructLayoutAttribute.Pack atau StructLayoutAttribute.Size, termasuk tata letak berurutan dan otomatis. Misalnya, jenis tata letak berurutan dengan Pack = 1 memerlukan pilihan eksplisit yang sama. Nilai yang tidak ditentukan atau nol tidak memicu aturan tambahan sendiri. Bidang statis dan konstanta dikecualikan. Untuk bidang backing yang disintesis, letakkan pengubah pada properti atau peristiwa pemilik.
Untuk pesan dan perbaikan CS9392 untuk penyimpanan sintesis lainnya, lihat Keamanan tata letak bidang.
Spesifikasi bahasa C#
Untuk informasi selengkapnya, lihat Kode tidak aman di Spesifikasi Bahasa C#. Spesifikasi bahasa adalah sumber definitif untuk sintaks dan penggunaan C#.
Untuk desain model keamanan memori yang diperbarui, lihat spesifikasi fitur keamanan memori.