Jenis referensi yang dapat diubah ke null
Dalam konteks nullable-oblivious, semua jenis referensi dapat diubah ke null. Jenis referensi nullable mengacu pada sekelompok fitur yang diaktifkan dalam konteks sadar null yang meminimalkan kemungkinan kode Anda menyebabkan runtime untuk melemparkan System.NullReferenceException. Jenis referensi dapat diubah ke null mencakup tiga fitur yang membantu Anda menghindari pengecualian ini, termasuk kemampuan untuk secara eksplisit menandai jenis referensi sebagai dapat diubah ke null:
- Peningkatan analisis aliran statis yang menentukan apakah variabel mungkin
null
sebelum mendereferensikannya. - Atribut yang membuat anotasi API sehingga analisis alur menentukan status null.
- Anotasi variabel yang digunakan pengembang untuk secara eksplisit mendeklarasikan status null yang dimaksudkan untuk variabel.
Pengkompilasi melacak status null setiap ekspresi dalam kode Anda pada waktu kompilasi. Status null memiliki salah satu dari tiga nilai:
- not-null: Ekspresi diketahui tidak-
null
. - mungkin-null: Ekspresinya mungkin
null
. - tidak sadar: Pengkompilasi tidak dapat menentukan status null ekspresi.
Anotasi variabel menentukan nullability variabel jenis referensi:
- tidak dapat diubah ke null: Jika Anda menetapkan
null
nilai atau ekspresi mungkin-null ke variabel, pengkompilasi mengeluarkan peringatan. Variabel yang tidak dapat diubah ke null memiliki status null default tidak-null. - nullable: Anda dapat menetapkan
null
nilai atau ekspresi mungkin-null ke variabel. Ketika status null variabel mungkin-null, kompilator mengeluarkan peringatan jika Anda mendereferensikan variabel. Status null default untuk variabel mungkin-null. - tidak sadar: Anda dapat menetapkan
null
nilai atau ekspresi mungkin-null ke variabel. Pengkompilasi tidak mengeluarkan peringatan saat Anda mendereferensikan variabel, atau saat Anda menetapkan ekspresi mungkin-null ke variabel.
Status null yang tidak jelas dan ketimpangan yang tidak jelas cocok dengan perilaku sebelum jenis referensi nullable diperkenalkan. Nilai-nilai tersebut berguna selama migrasi, atau saat aplikasi Anda menggunakan pustaka yang belum mengaktifkan jenis referensi nullable.
Analisis status null dan anotasi variabel dinonaktifkan secara default untuk proyek yang ada—yang berarti bahwa semua jenis referensi terus dapat diubah ke null. Mulai dari .NET 6, mereka diaktifkan secara default untuk proyek baru. Untuk informasi tentang mengaktifkan fitur-fitur ini dengan mendeklarasikan konteks anotasi yang dapat diubah ke null, lihat Konteks yang dapat diubah ke null.
Sisa artikel ini menjelaskan cara kerja ketiga area fitur tersebut untuk menghasilkan peringatan ketika kode Anda mungkin mendereferensikan null
nilai. Mendereferensikan variabel berarti mengakses salah satu anggotanya menggunakan operator .
(titik), seperti yang ditunjukkan dalam contoh berikut:
string message = "Hello, World!";
int length = message.Length; // dereferencing "message"
Ketika Anda mendereferensikan variabel yang nilainya adalah null
, runtime bahasa umum melempar System.NullReferenceException.
Anda akan mempelajari tentang:
- Analisis status null kompilator: bagaimana pengkompilasi menentukan apakah ekspresi tidak-null, atau mungkin-null.
- Atribut yang diterapkan ke API yang menyediakan lebih banyak konteks untuk analisis status null kompilator.
- Anotasi variabel nullable yang memberikan informasi tentang niat Anda untuk variabel. Anotasi berguna bagi bidang untuk mengatur status null default di awal metode anggota.
- Aturan yang mengatur argumen jenis generik. Batasan baru ditambahkan karena parameter jenis dapat berupa jenis referensi atau jenis nilai. Akhiran
?
diimplementasikan secara berbeda untuk jenis nilai nullable dan jenis referensi nullable. - Konteks nullable membantu Anda memigrasikan proyek besar. Anda dapat mengaktifkan konteks atau peringatan nullable di bagian aplikasi saat bermigrasi. Setelah mengatasi lebih banyak peringatan, Anda dapat mengaktifkan jenis referensi nullable untuk seluruh proyek.
Terakhir, Anda mempelajari perangkap yang diketahui untuk analisis status null dalam struct
jenis dan array.
Anda juga dapat menjelajahi konsep-konsep ini dalam modul Learn kami tentang keamanan Nullable di C#.
analisis status null
Ketika jenis referensi nullable diaktifkan, analisis null-state melacak status null referensi. Ekspresi tidak null atau mungkin-null. Kompilator menentukan bahwa variabel tidak null dalam dua cara:
- Variabel telah diberi nilai yang diketahui tidak-null.
- Variabel telah diperiksa terhadap
null
dan belum dimodifikasi sejak pemeriksaan itu.
Ketika jenis referensi nullable tidak diaktifkan, semua ekspresi memiliki status null tidak sadar. Bagian lainnya menjelaskan perilaku ketika jenis referensi nullable diaktifkan.
Variabel apa pun yang belum ditentukan kompilator karena tidak null dianggap mungkin null. Analisis ini memberikan peringatan dalam situasi di mana Anda mungkin secara tidak sengaja mendereferensikan null
nilai. Kompilator menghasilkan peringatan berdasarkan status null.
- Ketika variabel tidak-null, variabel tersebut mungkin didereferensikan dengan aman.
- Ketika variabel mungkin null, variabel tersebut harus diperiksa untuk memastikan bahwa variabel tersebut tidak
null
sebelum mendereferensikannya.
Pertimbangkan contoh berikut:
string message = null;
// warning: dereference null.
Console.WriteLine($"The length of the message is {message.Length}");
var originalMessage = message;
message = "Hello, World!";
// No warning. Analysis determined "message" is not-null.
Console.WriteLine($"The length of the message is {message.Length}");
// warning!
Console.WriteLine(originalMessage.Length);
Dalam contoh sebelumnya, kompilator menentukan bahwa message
adalah mungkin null ketika pesan pertama dicetak. Tidak ada peringatan untuk pesan kedua. Baris akhir kode menghasilkan peringatan karena originalMessage
mungkin null. Contoh berikut menunjukkan penggunaan yang lebih praktis untuk melintas pohon simpul ke akar, memproses setiap simpul selama traversal:
void FindRoot(Node node, Action<Node> processNode)
{
for (var current = node; current != null; current = current.Parent)
{
processNode(current);
}
}
Kode sebelumnya tidak menghasilkan peringatan apa pun untuk mendereferensi variabel current
. Analisis statis menentukan bahwa current
tidak pernah didereferensikan ketika mungkin null. Variabel current
diperiksa terhadap null
sebelum current.Parent
diakses, dan sebelum meneruskan current
ke tindakan ProcessNode
. Contoh sebelumnya menunjukkan bagaimana kompilator menentukan status null untuk variabel lokal saat diinisialisasi, ditetapkan, atau dibandingkan dengan null
.
Analisis status null tidak dilacak ke metode yang disebut. Akibatnya, bidang yang diinisialisasi dalam metode pembantu umum yang disebut oleh semua konstruktor menghasilkan peringatan dengan templat berikut:
Properti 'nama' yang tidak dapat diubah ke null harus berisi nilai tidak null saat keluar dari konstruktor.
Anda dapat mengatasi peringatan ini dengan salah satu dari dua cara: Penautan konstruktor, atau atribut dapat diubah ke null pada metode pembantu. Kode berikut menunjukkan contoh masing-masing. Kelas Person
menggunakan konstruktor umum yang dipanggil oleh semua konstruktor lain. Kelas Student
ini memiliki metode pembantu yang beranotasi dengan atribut System.Diagnostics.CodeAnalysis.MemberNotNullAttribute:
using System.Diagnostics.CodeAnalysis;
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public Person() : this("John", "Doe") { }
}
public class Student : Person
{
public string Major { get; set; }
public Student(string firstName, string lastName, string major)
: base(firstName, lastName)
{
SetMajor(major);
}
public Student(string firstName, string lastName) :
base(firstName, lastName)
{
SetMajor();
}
public Student()
{
SetMajor();
}
[MemberNotNull(nameof(Major))]
private void SetMajor(string? major = default)
{
Major = major ?? "Undeclared";
}
}
Catatan
Sejumlah peningkatan penetapan pasti dan analisis status null ditambahkan dalam C# 10. Ketika Anda meningkatkan ke C# 10, Anda mungkin menemukan lebih sedikit peringatan null yang positif palsu. Anda dapat mempelajari lebih lanjut tentang peningkatan dalam spesifikasi fitur untuk peningkatan penugasan yang pasti.
Analisis status yang dapat diubah ke null dan peringatan yang dihasilkan kompilator membantu Anda menghindari kesalahan program dengan mendereferensikan null
. Artikel tentang mengatasi peringatan nullable menyediakan teknik untuk mengoreksi peringatan yang kemungkinan besar terlihat dalam kode Anda.
Atribut pada tanda tangan API
Analisis status null membutuhkan petunjuk dari pengembang untuk memahami semantik API. Beberapa API memberikan pemeriksaan null, dan harus mengubah status null variabel dari mungkin null menjadi tidak null. API lain mengembalikan ekspresi yang tidak null atau mungkin null tergantung pada status null argumen input. Misalnya, pertimbangkan kode berikut yang menampilkan pesan dalam huruf besar:
void PrintMessageUpper(string? message)
{
if (!IsNull(message))
{
Console.WriteLine($"{DateTime.Now}: {message.ToUpper()}");
}
}
bool IsNull(string? s) => s == null;
Berdasarkan inspeksi, setiap pengembang akan menganggap kode ini aman, dan tidak boleh menghasilkan peringatan. Namun pengkompilasi tidak tahu bahwa IsNull
memberikan pemeriksaan null dan mengeluarkan peringatan untuk pernyataan, message.ToUpper()
mengingat message
sebagai variabel mungkin-null . NotNullWhen
Gunakan atribut untuk memperbaiki peringatan ini:
bool IsNull([NotNullWhen(false)] string? s) => s == null;
Atribut ini menginformasikan pengkompilasi, bahwa, jika IsNull
mengembalikan false
, parameternya s
tidak null. Pengkompilasi mengubah status null menjadi message
tidak-null di if (!IsNull(message)) {...}
dalam blok. Tidak ada peringatan yang dikeluarkan.
Atribut memberikan informasi terperinci tentang status null argumen, nilai pengembalian, dan anggota instans objek yang digunakan untuk memanggil anggota. Detail pada setiap atribut dapat ditemukan di artikel referensi bahasa pada atribut referensi yang dapat diubah ke null. Pada .NET 5, semua API runtime .NET dianotasi. Anda meningkatkan analisis statis dengan menganotasi API Anda untuk memberikan informasi semantik tentang status null argumen dan mengembalikan nilai.
Anotasi variabel yang dapat diubah ke null
Analisis status null menyediakan analisis yang kuat untuk variabel lokal. Kompilator membutuhkan informasi lebih lanjut dari Anda untuk variabel anggota. Pengompilasi memerlukan informasi lebih lanjut untuk mengatur status null dari semua bidang pada tanda kurung buka anggota. Salah satu konstruktor yang dapat diakses dapat digunakan untuk menginisialisasi objek. Jika bidang anggota mungkin pernah diatur ke null
, kompilator harus mengasumsikan status null-nya adalah mungkin null di awal setiap metode.
Anda menggunakan anotasi yang dapat mendeklarasikan apakah variabel adalah jenis referensi dapat diubah ke null atau jenis referensi yang tidak dapat diubah ke null. Anotasi ini membuat pernyataan penting tentang status null untuk variabel:
- Referensi tidak seharusnya null. Status default variabel referensi yang tidak dapat diubah ke null bukan nol. Kompilator memberlakukan aturan yang memastikan aman untuk mendereferensikan variabel ini tanpa terlebih dahulu memeriksa bahwa variabel tersebut bukan null:
- Variabel harus diinisialisasi ke nilai tidak null.
- Variabel tidak pernah dapat ditetapkan nilainya
null
. Kompilator mengeluarkan peringatan ketika kode menetapkan ekspresi mungkin null ke variabel yang seharusnya tidak null.
- Referensi mungkin null. Status default variabel referensi yang dapat diubah ke null mungkin null. Pengkompilasi memberlakukan aturan untuk memastikan bahwa Anda memeriksa
null
referensi dengan benar:- Variabel mungkin hanya didereferensikan ketika pengkompilasi dapat menjamin bahwa nilainya bukan
null
. - Variabel ini mungkin diinisialisasi dengan nilai default
null
dan mungkin diberi nilainull
dalam kode lain. - Pengkompilasi tidak mengeluarkan peringatan saat kode menetapkan ekspresi mungkin-null ke variabel yang mungkin null.
- Variabel mungkin hanya didereferensikan ketika pengkompilasi dapat menjamin bahwa nilainya bukan
Variabel referensi yang tidak dapat diubah ke null memiliki status null default tidak-null. Variabel referensi yang dapat diubah ke null memiliki status null awal mungkin-null.
Jenis referensi yang dapat diubah ke null dicatat menggunakan sintaks yang sama dengan tipe nilai yang dapat diubah ke null: ?
ditambahkan ke jenis variabel. Misalnya, deklarasi variabel berikut mewakili variabel string yang dapat diubah ke null, name
:
string? name;
Ketika jenis referensi nullable diaktifkan, variabel apa pun di mana ?
tidak ditambahkan ke nama jenis adalah jenis referensi yang tidak dapat diubah ke null. Itu termasuk semua variabel jenis referensi dalam kode yang ada setelah Anda mengaktifkan fitur ini. Namun, variabel lokal yang diketik secara implisit (dinyatakan menggunakan var
) adalah jenis referensi yang dapat diubah ke null. Seperti yang ditunjukkan bagian sebelumnya, analisis statis menentukan status null variabel lokal untuk menentukan apakah variabel tersebut mungkin-null sebelum mendereferensikannya.
Terkadang Anda harus mengambil alih peringatan ketika Anda tahu variabel tidak null, tetapi kompilator menentukan status null-nya adalah mungkin null. Anda menggunakan operator !
null-forgiving dengan mengikuti nama variabel untuk memaksa status null menjadi tidak-null. Misalnya, jika Anda tahu name
variabelnya bukan null
tetapi kompilator mengeluarkan peringatan, Anda dapat menulis kode berikut untuk mengambil alih analisis kompilator:
name!.Length;
Jenis referensi nullable dan jenis nilai nullable menyediakan konsep semantik serupa: Variabel dapat mewakili nilai atau objek, atau variabel tersebut mungkin null
. Namun, jenis referensi yang dapat diubah ke null dan jenis nilai yang dapat diubah ke null diimplementasikan secara berbeda: jenis nilai yang dapat diubah ke null diimplementasikan menggunakan System.Nullable<T>, dan jenis referensi null diimplementasikan oleh atribut yang dibaca oleh kompilator. Misalnya, string?
dan string
keduanya diwakili oleh jenis yang sama: System.String. Namun, int?
dan int
masing-masing diwakili oleh System.Nullable<System.Int32>
dan System.Int32.
Jenis referensi yang dapat diubah ke null adalah fitur waktu kompilasi. Itu berarti dimungkinkan bagi penelepon untuk mengabaikan peringatan, dengan sengaja menggunakan null
sebagai argumen untuk metode yang mengharapkan referensi yang tidak dapat diubah ke null. Penulis pustaka harus menyertakan pemeriksaan run-time terhadap nilai argumen null. ArgumentNullException.ThrowIfNull adalah opsi yang disukai untuk memeriksa parameter terhadap null pada durasi.
Penting
Mengaktifkan anotasi yang dapat diubah ke null dapat mengubah bagaimana Entity Framework Core menentukan apakah anggota data diperlukan. Anda dapat mempelajari detail selengkapnya dalam artikel tentang Dasar-Dasar Inti Entity Framework: Bekerja dengan Jenis Referensi Yang Dapat Diubah Ke null.
Generik
Generik memerlukan aturan terperinci guna menangani T?
untuk parameter T
jenis apa pun. Aturan harus dirinci karena riwayat dan implementasi yang berbeda untuk jenis nilai yang dapat diubah ke null dan jenis referensi yang dapat diubah ke null. Jenis nilai yang dapat diubah ke null diimplementasikan menggunakan struktur System.Nullable<T>. Jenis referensi yang dapat diubah ke null diimplementasikan sebagai anotasi jenis yang menyediakan aturan semantik kepada kompilator.
- Jika argumen jenis untuk
T
adalah jenis referensi,T?
mereferensikan jenis referensi yang dapat diubah ke null yang sesuai. Misalnya, jikaT
adalahstring
, makaT?
adalahstring?
. - Jika argumen jenis untuk
T
adalah jenis nilai,T?
mereferensikan jenis nilai yang sama,T
. Misalnya, jikaT
adalahint
, makaT?
juga merupakanint
. - Jika argumen jenis untuk
T
adalah jenis referensi yang dapat diubah ke null,T?
mereferensikannya jenis referensi yang dapat diubah ke null yang sama. Misalnya, jikaT
adalahstring?
, makaT?
juga merupakanstring?
. - Jika argumen jenis untuk
T
adalah jenis nilai yang dapat diubah ke null,T?
mereferensikannya jenis nilai yang dapat diubah ke null yang sama. Misalnya, jikaT
adalahint?
, makaT?
juga merupakanint?
.
Untuk nilai yang dikembalikan, T?
setara dengan [MaybeNull]T
; untuk nilai argumen, T?
setara dengan [AllowNull]T
. Untuk informasi selengkapnya, lihat artikel tentang Atribut untuk analisis status nol dalam referensi bahasa.
Anda dapat menentukan perilaku yang berbeda menggunakan batasan:
- Batasan
class
berarti bahwaT
harus merupakan jenis referensi yang tidak dapat diubah ke null (misalnyastring
). Kompilator menghasilkan peringatan jika Anda menggunakan jenis referensi yang dapat diubah ke null, sepertistring?
untukT
. - Batasan
class?
berarti bahwaT
harus merupakan jenis referensi, baik yang tidak dapat diubah ke null (string
) atau jenis referensi yang dapat diubah ke null (misalnyastring?
). Ketika parameter jenis adalah jenis referensi yang dapat diubah ke null, sepertistring?
, ekspresi dari referensiT?
yang sama dengan jenis referensi yang dapat diubah ke null, sepertistring?
. - Batasan
notnull
berarti bahwaT
harus merupakan jenis referensi yang tidak dapat diubah ke null, atau jenis nilai yang tidak dapat diubah ke null. Jika Anda menggunakan jenis referensi yang dapat diubah ke null atau jenis nilai yang dapat diubah ke null untuk parameter jenis, kompilator akan menghasilkan peringatan. Selain itu, ketikaT
adalah jenis nilai, nilai yang dikembalikan adalah jenis nilai tersebut, bukan jenis nilai yang dapat diubah ke null yang sesuai.
Batasan ini membantu memberikan informasi lebih lanjut kepada pengkompilasi tentang cara T
digunakan. Itu membantu ketika pengembang memilih jenis untuk T
dan memberikan analisis status null yang lebih baik saat instans jenis generik digunakan.
Konteks yang dapat diubah ke null
Untuk proyek kecil, Anda dapat mengaktifkan jenis referensi nullable, memperbaiki peringatan, dan melanjutkan. Namun, untuk proyek yang lebih besar dan solusi multi-proyek, yang mungkin menghasilkan sejumlah besar peringatan. Anda dapat menggunakan pragmas untuk mengaktifkan jenis referensi nullable file-by-file saat Anda mulai menggunakan jenis referensi nullable. Fitur baru yang melindungi dari melempar System.NullReferenceException dapat mengganggu saat diaktifkan di basis kode yang ada:
- Semua variabel referensi yang diketik secara eksplisit ditafsirkan sebagai jenis referensi yang tidak dapat diubah ke null.
- Arti batasan
class
dalam generik berubah menjadi berarti jenis referensi yang tidak dapat diubah ke null. - Peringatan baru dihasilkan karena aturan baru ini.
Konteks anotasi yang dapat diubah ke null menentukan perilaku kompilator. Ada empat nilai untuk konteks anotasi yang dapat diubah ke null:
- disable: Kode nullable-oblivious. Nonaktifkan kecocokan perilaku sebelum jenis referensi null diaktifkan, kecuali sintaks baru menghasilkan peringatan alih-alih kesalahan.
- Peringatan yang dapat diubah ke null dinonaktifkan.
- Semua variabel jenis referensi adalah jenis referensi yang dapat diubah ke null.
- Penggunaan akhiran
?
untuk mendeklarasikan jenis referensi yang dapat diubah ke null menghasilkan peringatan. - Anda dapat menggunakan operator pengampunan null,
!
, tetapi tidak berpengaruh.
- aktifkan: Kompilator memungkinkan semua analisis referensi null dan semua fitur bahasa.
- Semua peringatan baru yang dapat diubah ke null diaktifkan.
- Anda dapat menggunakan akhiran
?
untuk mendeklarasikan jenis referensi yang dapat diubah ke null. - Variabel jenis referensi tanpa akhiran
?
adalah jenis referensi yang tidak dapat diubah ke null. - Operator pengampunan null menekan peringatan untuk kemungkinan penugasan ke
null
.
- peringatan: Kompilator melakukan semua analisis null dan memancarkan peringatan ketika kode mungkin dereferensi
null
.- Semua peringatan baru yang dapat diubah ke null diaktifkan.
- Penggunaan akhiran
?
untuk mendeklarasikan jenis referensi yang dapat diubah ke null menghasilkan peringatan. - Semua variabel jenis referensi diperbolehkan null. Namun, anggota memiliki status null dari not null pada kurung kurawal pembuka dari semua metode kecuali dinyatakan dengan akhiran
?
. - Anda dapat menggunakan operator pengampunan null,
!
.
- anotasi: Pengompilasi tidak memancarkan peringatan ketika kode mungkin dereferensi
null
, atau saat Anda menetapkan ekspresi mungkin-null ke variabel yang tidak dapat diubah ke null.- Semua peringatan baru yang dapat diubah ke null dinonaktifkan.
- Anda dapat menggunakan akhiran
?
untuk mendeklarasikan jenis referensi yang dapat diubah ke null. - Variabel jenis referensi tanpa akhiran
?
adalah jenis referensi yang tidak dapat diubah ke null. - Anda dapat menggunakan operator pengampunan null,
!
, tetapi tidak berpengaruh.
Konteks anotasi yang dapat diubah ke null dan konteks peringatan yang dapat diubah ke null dapat diatur untuk proyek menggunakan <Nullable>
elemen dalam file .csproj Anda. Elemen ini mengonfigurasi bagaimana kompilator menginterpretasikan nullability jenis dan peringatan apa yang dipancarkan. Tabel berikut ini memperlihatkan nilai yang diizinkan dan meringkas konteks yang mereka tentukan.
Konteks | Peringatan dereferensi | Peringatan penugasan | Jenis referensi | ? akhiran |
! operator |
---|---|---|---|---|---|
disable |
Nonaktif | Nonaktif | Semua dapat diubah ke null | Menghasilkan peringatan | Tidak berpengaruh |
enable |
Diaktifkan | Diaktifkan | Tidak dapat diubah ke null kecuali dinyatakan dengan ? |
Mendeklarasikan jenis yang dapat diubah ke null | Menyembunyikan peringatan untuk kemungkinan penugasan null |
warnings |
Diaktifkan | Tidak berlaku | Semua nullable, tetapi anggota dianggap tidak-null saat membuka kurung metode | Menghasilkan peringatan | Menyembunyikan peringatan untuk kemungkinan penugasan null |
annotations |
Nonaktif | Nonaktif | Tidak dapat diubah ke null kecuali dinyatakan dengan ? |
Mendeklarasikan jenis yang dapat diubah ke null | Tidak berpengaruh |
Variabel jenis referensi dalam kode yang dikompilasi dalam konteks yang dinonaktifkan adalah nullable-oblivious. Anda dapat menetapkan null
variabel harfiah atau mungkin-null ke variabel yang nullable-oblivious. Namun, status default variabel dapat diubah menjadi null-oblivious adalah tidak null.
Anda dapat memilih pengaturan mana yang terbaik untuk proyek Anda:
- Pilih nonaktifkan untuk proyek lama yang tidak ingin Anda perbarui berdasarkan diagnostik atau fitur baru.
- Pilih peringatan untuk menentukan di mana kode Anda mungkin melemparkan System.NullReferenceException. Anda dapat mengatasi peringatan tersebut sebelum memodifikasi kode untuk mengaktifkan jenis referensi yang tidak dapat diubah ke null.
- Pilih anotasi untuk mengekspresikan niat desain Anda sebelum mengaktifkan peringatan.
- Pilih aktifkan untuk proyek baru dan proyek aktif tempat Anda ingin melindungi dari pengecualian referensi null.
Contoh:
<Nullable>enable</Nullable>
Anda juga dapat menggunakan arahan untuk mengatur konteks yang sama ini di mana saja dalam kode sumber Anda. Arahan ini paling berguna saat Anda memigrasikan basis kode besar.
#nullable enable
: Menetapkan konteks anotasi yang dapat diubah ke null dan konteks peringatan yang dapat diubah ke null untuk mengaktifkan.#nullable disable
: Menetapkan konteks anotasi yang dapat diubah ke null dan konteks peringatan yang dapat diubah ke null untuk menonaktifkan.#nullable restore
: Memulihkan konteks anotasi yang dapat diubah ke null dan konteks peringatan yang dapat diubah ke null ke pengaturan proyek.#nullable disable warnings
: Mengatur konteks peringatan yang dapat diubah ke null untuk menonaktifkan.#nullable enable warnings
: Mengatur konteks peringatan yang dapat diubah ke null untuk mengaktifkan.#nullable restore warnings
: Memulihkan konteks peringatan yang dapat diubah ke null ke pengaturan proyek.#nullable disable annotations
: Mengatur konteks anotasi yang dapat diubah ke null untuk menonaktifkan.#nullable enable annotations
: Mengatur konteks anotasi yang dapat diubah ke null untuk mengaktifkan.#nullable restore annotations
: Memulihkan konteks peringatan anotasi ke pengaturan proyek.
Untuk baris kode apa pun, Anda dapat mengatur salah satu kombinasi berikut:
Konteks peringatan | Konteks anotasi | Menggunakan |
---|---|---|
default proyek | default proyek | Default |
enable | nonaktifkan | Memperbaiki peringatan analisis |
enable | default proyek | Memperbaiki peringatan analisis |
default proyek | enable | Menambahkan anotasi jenis |
enable | enable | Kode sudah dimigrasikan |
nonaktifkan | enable | Melakukan anotasi kode sebelum memperbaiki peringatan |
nonaktifkan | nonaktifkan | Menambahkan kode lama ke proyek yang dimigrasikan |
default proyek | nonaktifkan | Jarang |
nonaktifkan | default proyek | Jarang |
Sembilan kombinasi tersebut memberi Anda kontrol terperinci atas diagnostik yang dikeluarkan kompilator untuk kode Anda. Anda dapat mengaktifkan lebih banyak fitur di area mana pun yang Anda perbarui, tanpa melihat lebih banyak peringatan yang belum siap Anda atasi.
Penting
Konteks global yang dapat diubah ke null tidak berlaku untuk file kode yang dihasilkan. Di bawah salah satu strategi, konteks yang dapat diubah ke null dinonaktifkan untuk file sumber apa pun yang ditandai sebagai dihasilkan. Ini berarti API apa pun dalam file yang dihasilkan tidak dianotasi. Ada empat cara file ditandai sebagai dihasilkan:
- Dalam .editorconfig, tentukan
generated_code = true
di bagian yang berlaku untuk file tersebut. - Memasukkan
<auto-generated>
atau<auto-generated/>
pada komentar di bagian atas file. Ini bisa berada di baris mana pun dalam komentar itu, tetapi blok komentar harus menjadi elemen pertama dalam file. - Memulai nama file dengan TemporaryGeneratedFile_
- Mengakhiri nama file dengan .designer.cs, .generated.cs, .g.cs, atau .g.i.cs.
Generator dapat ikut serta dengan menggunakan direktif pra-prosesor #nullable
.
Secara default, anotasi null dan konteks peringatan dinonaktifkan. Itu berarti bahwa kode Anda yang ada dikompilasi tanpa perubahan dan tanpa menghasilkan peringatan baru. Dimulai dengan .NET 6, proyek baru menyertakan elemen <Nullable>enable</Nullable>
di semua templat proyek.
Opsi ini menyediakan dua strategi berbeda untuk memperbarui basis kode yang ada untuk menggunakan jenis referensi yang dapat diubah ke null.
Perangkap yang diketahui
Larik dan struktur yang berisi jenis referensi adalah jebakan yang diketahui dalam referensi yang dapat diubah ke null dan analisis statis yang menentukan keamanan null. Dalam kedua situasi, referensi yang tidak dapat diubah ke null mungkin diinisialisasi ke null
, tanpa menghasilkan peringatan.
Structs
Struktur yang berisi jenis referensi yang tidak dapat diubah ke null memungkinkan penetapan default
untuknya tanpa peringatan apa pun. Pertimbangkan contoh berikut:
using System;
#nullable enable
public struct Student
{
public string FirstName;
public string? MiddleName;
public string LastName;
}
public static class Program
{
public static void PrintStudent(Student student)
{
Console.WriteLine($"First name: {student.FirstName.ToUpper()}");
Console.WriteLine($"Middle name: {student.MiddleName?.ToUpper()}");
Console.WriteLine($"Last name: {student.LastName.ToUpper()}");
}
public static void Main() => PrintStudent(default);
}
Dalam contoh sebelumnya, tidak ada peringatan pada PrintStudent(default)
saat jenis referensi yang tidak dapat diubah ke null FirstName
dan LastName
adalah null.
Kasus lain yang lebih umum adalah ketika Anda berurusan dengan struktur generik. Pertimbangkan contoh berikut:
#nullable enable
public struct S<T>
{
public T Prop { get; set; }
}
public static class Program
{
public static void Main()
{
string s = default(S<string>).Prop;
}
}
Dalam contoh sebelumnya, properti Prop
berada null
pada waktu proses. Ini ditetapkan ke string yang tidak dapat diubah ke null tanpa peringatan apa pun.
Larik
Array juga merupakan perangkap yang diketahui dalam jenis referensi yang dapat diubah ke null. Pertimbangkan contoh berikut yang tidak menghasilkan peringatan apa pun:
using System;
#nullable enable
public static class Program
{
public static void Main()
{
string[] values = new string[10];
string s = values[0];
Console.WriteLine(s.ToUpper());
}
}
Dalam contoh sebelumnya, deklarasi array menunjukkan ia memegang string yang tidak dapat diubah ke null, sementara elemennya semuanya diinisialisasi ke null
. Kemudian, variabel s
ditetapkan nilai null
(elemen pertama dari array). Akhirnya, variabel s
didereferensikan menyebabkan pengecualian runtime bahasa umum.