Mengatasi peringatan nullable
Artikel ini membahas peringatan pengkompilasi berikut:
- Nilai CS8597 - Thrown mungkin null.
- CS8600 - Mengonversi harfiah null atau kemungkinan nilai null ke jenis yang tidak dapat diubah ke null.
- CS8601 - Kemungkinan penetapan referensi null.
- Dereferensi CS8602 - dari referensi yang mungkin null.
- CS8603 - Kemungkinan pengembalian referensi null.
- CS8604 - Kemungkinan argumen referensi null untuk parameter.
- CS8605 - Membuka kotak mungkin nilai null.
- CS8607 - Nilai null yang mungkin tidak digunakan untuk jenis yang ditandai dengan
[NotNull]
atau[DisallowNull]
- CS8608 - Nullability jenis referensi dalam jenis tidak cocok dengan anggota yang ditimpa.
- CS8609 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan anggota yang ditimpa.
- CS8610 - Nullability jenis referensi dalam parameter jenis tidak cocok dengan anggota yang ditimpa.
- CS8611 - Nullability jenis referensi dalam parameter jenis tidak cocok dengan deklarasi metode parsial.
- CS8612 - Nullability jenis referensi dalam jenis tidak cocok dengan anggota yang diimplementasikan secara implisit.
- CS8613 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan anggota yang diimplementasikan secara implisit.
- CS8614 - Nullability jenis referensi dalam jenis parameter tidak cocok dengan anggota yang diimplementasikan secara implisit.
- CS8615 - Nullability jenis referensi dalam jenis tidak cocok dengan anggota yang diimplementasikan.
- CS8616 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan anggota yang diimplementasikan.
- CS8617 - Nullability jenis referensi dalam jenis parameter tidak cocok dengan anggota yang diimplementasikan.
- Variabel CS8618 - Non-nullable harus berisi nilai non-null saat keluar dari konstruktor. Pertimbangkan untuk mendeklarasikannya sebagai nullable.
- CS8619 - Nullability jenis referensi dalam nilai tidak cocok dengan jenis target.
- Argumen CS8620 - tidak dapat digunakan untuk parameter karena perbedaan dalam nullability jenis referensi.
- CS8621 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan delegasi target (mungkin karena atribut nullability).
- CS8622 - Nullability jenis referensi dalam jenis parameter tidak cocok dengan delegasi target (mungkin karena atribut nullability).
- Argumen CS8624 - tidak dapat digunakan sebagai output karena perbedaan dalam nullability jenis referensi.
- CS8625 - Tidak dapat mengonversi literal null ke tipe referensi yang tidak dapat diubah ke null.
- Jenis nilai CS8629 - Nullable mungkin null.
- CS8631 - Jenis tidak dapat digunakan sebagai parameter jenis dalam jenis atau metode generik. Nullability dari jenis argumen tidak cocok dengan jenis batasan.
- CS8633 - Nullability dalam batasan untuk parameter jenis metode tidak cocok dengan batasan untuk parameter jenis metode antarmuka. Pertimbangkan untuk menggunakan implementasi antarmuka eksplisit sebagai gantinya.
- CS8634 - Jenis tidak dapat digunakan sebagai parameter jenis dalam jenis atau metode generik. Kemampuan null tipe argumen tidak cocok dengan batasan 'kelas'.
- CS8643 - Nullability jenis referensi dalam penentu antarmuka eksplisit tidak cocok dengan antarmuka yang diterapkan oleh jenis .
- Tipe CS8644 - tidak menerapkan anggota antarmuka. Nullability jenis referensi dalam antarmuka yang diimplementasikan oleh jenis dasar tidak cocok.
- Anggota CS8645 - sudah tercantum dalam daftar antarmuka pada jenis dengan berbagai nullability jenis referensi.
- CS8655 - Ekspresi pengalihan tidak menangani beberapa input null (tidak lengkap).
- Deklarasi metode parsial CS8667 - memiliki nullability yang tidak konsisten dalam batasan untuk parameter jenis.
- Objek CS8670 - atau penginisialisasi koleksi secara implisit mendereferensikan kemungkinan anggota null.
- CS8714 - Jenis tidak dapat digunakan sebagai parameter jenis dalam jenis atau metode generik. Nullability dari jenis argumen tidak cocok dengan batasan 'notnull'.
- Parameter CS8762 - harus memiliki nilai non-null saat keluar.
- Metode CS8763 - A yang ditandai
[DoesNotReturn]
tidak boleh dikembalikan. - CS8764 - Nullability jenis pengembalian tidak cocok dengan anggota yang ditimpa (mungkin karena atribut nullability).
- CS8765 - Nullability jenis parameter tidak cocok dengan anggota yang ditimpa (mungkin karena atribut nullability).
- CS8766 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan anggota yang diimplementasikan secara implisit (mungkin karena atribut nullability).
- CS8767 - Nullability jenis referensi dalam jenis parameter tidak cocok dengan anggota yang diimplementasikan secara implisit (mungkin karena atribut nullability).
- CS8768 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan anggota yang diimplementasikan (mungkin karena atribut nullability).
- CS8769 - Nullability jenis referensi dalam jenis parameter tidak cocok dengan anggota yang diimplementasikan (mungkin karena atribut nullability).
- Metode CS8770 - tidak memiliki
[DoesNotReturn]
anotasi agar sesuai dengan anggota yang diimplementasikan atau ditimpa. - Anggota CS8774 - harus memiliki nilai non-null saat keluar.
- Anggota CS8776 - tidak dapat digunakan dalam atribut ini.
- Anggota CS8775 - harus memiliki nilai non-null saat keluar.
- Parameter CS8777 - harus memiliki nilai non-null saat keluar.
- CS8819 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan deklarasi metode parsial.
- Parameter CS8824 - harus memiliki nilai non-null saat keluar karena parameter non-null.
- Nilai CS8825 - Return harus non-null karena parameter non-null.
- CS8847 - Ekspresi pengalihan tidak menangani beberapa input null (tidak lengkap). Namun, pola dengan klausa 'kapan' mungkin berhasil mencocokkan nilai ini.
Tujuan peringatan nullable adalah untuk meminimalkan kemungkinan aplikasi Anda melempar saat System.NullReferenceException dijalankan. Untuk mencapai tujuan ini, kompilator menggunakan analisis statis dan mengeluarkan peringatan ketika kode Anda memiliki konstruksi yang dapat menyebabkan pengecualian referensi null. Anda memberikan informasi kepada kompilator untuk analisis statisnya dengan menerapkan anotasi dan atribut jenis. Anotasi dan atribut ini menjelaskan kemampuan untuk dapat diubah ke null dari argumen, parameter, dan anggota jenis Anda. Dalam artikel ini, Anda akan mempelajari berbagai teknik untuk mengatasi peringatan yang dapat diubah ke null yang dihasilkan kompilator dari analisis statisnya. Teknik yang dijelaskan di sini adalah untuk kode C# umum. Pelajari cara bekerja dengan jenis referensi yang dapat diubah ke null dan inti Entity Framework dalam Bekerja dengan jenis referensi yang dapat diubah ke null.
Anda akan mengatasi hampir semua peringatan menggunakan salah satu dari empat teknik:
- Menambahkan pemeriksaan null yang diperlukan.
- Menambahkan anotasi yang dapat diubah ke null
?
atau!
. - Menambahkan atribut yang menjelaskan semantik null.
- Menginisialisasi variabel dengan benar.
Kemungkinan dereferensi null
Set peringatan ini memperingatkan Anda bahwa Anda mendereferensiasi variabel yang status null-nya mungkin-null. Peringatan ini adalah:
- Dereferensi CS8602 - dari referensi yang mungkin null.
- Objek CS8670 - atau penginisialisasi koleksi secara implisit mendereferensikan kemungkinan anggota null.
Kode berikut menunjukkan satu contoh dari setiap peringatan sebelumnya:
class Container
{
public List<string>? States { get; set; }
}
internal void PossibleDereferenceNullExamples(string? message)
{
Console.WriteLine(message.Length); // CS8602
var c = new Container { States = { "Red", "Yellow", "Green" } }; // CS8670
}
Dalam contoh di atas, peringatannya adalah karena Container
, , c
mungkin memiliki nilai null untuk States
properti . Menetapkan status baru ke koleksi yang mungkin null menyebabkan peringatan.
Untuk menghapus peringatan ini, Anda perlu menambahkan kode untuk mengubah status-null variabel tersebut menjadi tidak-null sebelum melakukan dereferensi padanya. Peringatan penginisialisasi koleksi mungkin lebih sulit ditemukan. Pengkompilasi mendeteksi bahwa koleksi mungkin null ketika penginisialisasi menambahkan elemen ke dalamnya.
Dalam banyak instans, Anda dapat memperbaiki peringatan ini dengan memeriksa bahwa variabel tidak null sebelum melakukan dereferensi padanya. Pertimbangkan hal berikut yang menambahkan pemeriksaan null sebelum mendereferensikan message
parameter:
void WriteMessageLength(string? message)
{
if (message is not null)
{
Console.WriteLine(message.Length);
}
}
Contoh berikut menginisialisasi penyimpanan cadangan untuk States
dan menghapus set
aksesor. Konsumen kelas dapat memodifikasi konten koleksi, dan penyimpanan untuk koleksi tidak pernah null
:
class Container
{
public List<string> States { get; } = new();
}
Instans lain ketika Anda mendapatkan peringatan ini mungkin positif palsu. Anda mungkin memiliki metode utilitas privat yang menguji null. Kompilator tidak tahu bahwa metode menyediakan pemeriksaan null. Pertimbangkan contoh berikut yang menggunakan metode utilitas privat, IsNotNull
:
public void WriteMessage(string? message)
{
if (IsNotNull(message))
Console.WriteLine(message.Length);
}
Kompilator memperingatkan bahwa Anda mungkin melakukan dereferensi null ketika Anda menulis properti message.Length
karena analisis statisnya menentukan bahwa message
mungkin null
. Anda mungkin tahu bahwa IsNotNull
memberikan pemeriksaan null, dan ketika mengembalikan true
, status null dari message
seharusnya tidak-null. Anda harus memberitahu kompilator fakta tersebut. Salah satu caranya adalah dengan menggunakan operator pengampunan null, !
. Anda dapat mengubah pernyataan WriteLine
agar cocok dengan kode berikut:
Console.WriteLine(message!.Length);
Operator pengampunan null membuat ekspresi tidak null meskipun itu adalah mungkin-null tanpa !
diterapkan. Dalam contoh ini, solusi yang lebih baik adalah menambahkan atribut ke tanda tangan IsNotNull
:
private static bool IsNotNull([NotNullWhen(true)] object? obj) => obj != null;
System.Diagnostics.CodeAnalysis.NotNullWhenAttribute menginformasikan kompilator bahwa argumen yang digunakan untuk parameter obj
adalah tidak nullketika metode mengembalikan true
. Ketika metode mengembalikan false
, argumen memiliki status null yang sama dengan sebelum metode dipanggil.
Tip
Ada sekumpulan atribut kaya yang dapat Anda gunakan untuk menjelaskan bagaimana metode dan properti Anda memengaruhi status null. Anda dapat mempelajarinya di artikel referensi bahasa pemrograman di atribut analisis statis yang dapat diubah ke null.
Memperbaiki peringatan untuk dereferensi variabel mungkin-null melibatkan salah satu dari tiga teknik:
- Tambahkan pemeriksaan null yang hilang.
- Tambahkan atribut analisis null pada API untuk memengaruhi analisis statis status null kompilator. Atribut ini menginformasikan kompilator ketika nilai atau argumen kembali harus mungkin-null atau tidak-null setelah memanggil metode.
- Terapkan operator pengampunan null
!
ke ekspresi untuk memaksa status menjadi tidak-null.
Kemungkinan null ditetapkan ke referensi yang tidak diubah ke null
Set peringatan ini memperingatkan Anda bahwa Anda menetapkan variabel yang jenisnya tidak dapat dinulelasikan ke ekspresi yang status null-nya mungkin-null. Peringatan ini adalah:
- Nilai CS8597 - Thrown mungkin null.
- CS8600 - Mengonversi harfiah null atau kemungkinan nilai null ke jenis yang tidak dapat diubah ke null.
- CS8601 - Kemungkinan penetapan referensi null.
- CS8603 - Kemungkinan pengembalian referensi null.
- CS8604 - Kemungkinan argumen referensi null untuk parameter.
- CS8605 - Membuka kotak mungkin nilai null.
- CS8625 - Tidak dapat mengonversi literal null ke tipe referensi yang tidak dapat diubah ke null.
- Jenis nilai CS8629 - Nullable mungkin null.
Kompilator mengeluarkan peringatan ini ketika Anda mencoba menetapkan ekspresi yang mungkin null ke variabel yang tidak dapat diubah ke null. Contohnya:
string? TryGetMessage(int id) => "";
string msg = TryGetMessage(42); // Possible null assignment.
Peringatan yang berbeda menunjukkan memberikan detail tentang kode, seperti penugasan, penetapan pembatalan kotak, pernyataan pengembalian, argumen ke metode, dan ekspresi lemparan.
Anda dapat mengambil salah satu dari tiga tindakan untuk mengatasi peringatan ini. Salah satunya adalah menambahkan anotasi ?
untuk menjadikan variabel sebagai jenis referensi yang dapat diubah ke null. Perubahan tersebut dapat menyebabkan peringatan lainnya. Mengubah variabel dari referensi yang tidak dapat diubah ke null menjadi referensi yang dapat diubah ke null mengubah default status nullnya dari tidak-null menjadi mungkin-null. Analisis statis kompilator mungkin menemukan instans di mana Anda melakukan dereferensi variabel yang mungkin null.
Tindakan lain menginstruksikan kompilator bahwa sisi kanan penugasan adalah tidak null. Ekspresi di sisi kanan dapat diperiksa null sebelum penugasan, seperti yang ditunjukkan dalam contoh berikut:
string notNullMsg = TryGetMessage(42) ?? "Unknown message id: 42";
Contoh sebelumnya menunjukkan penetapan nilai pengembalian metode. Anda dapat membuat anotasi metode (atau properti) untuk menunjukkan kapan metode mengembalikan nilai tidak null. System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute sering menentukan bahwa nilai yang dikembalikan tidak-null ketika argumen input tidak-null. Alternatif lain adalah menambahkan operator pengampunan null, !
ke sisi kanan:
string msg = TryGetMessage(42)!;
Memperbaiki peringatan untuk menetapkan ekspresi mungkin-null ke variabel tidak null melibatkan salah satu dari empat teknik:
- Ubah sisi kiri penugasan menjadi jenis yang dapat diubah ke null. Tindakan ini dapat memperkenalkan peringatan baru saat Anda melakukan dereferensi variabel tersebut.
- Berikan pemeriksaan null sebelum penugasan.
- Beri anotasi pada API yang menghasilkan sisi kanan penugasan.
- Tambahkan operator pengampunan null ke sisi kanan penugasan.
Referensi yang tidak dapat diubah ke null tidak diinisialisasi
Kumpulan peringatan ini memperingatkan Anda bahwa Anda menetapkan variabel yang jenisnya tidak dapat diubah ke ekspresi yang status null-nya mungkin-null. Peringatan ini adalah:
- Variabel CS8618 - Non-nullable harus berisi nilai non-null saat keluar dari konstruktor. Pertimbangkan untuk mendeklarasikannya sebagai nullable.
- Parameter CS8762 - harus memiliki nilai non-null saat keluar.
Pertimbangkan kelas berikut sebagai contoh:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Baik FirstName
maupun LastName
tidak dijamin diinisialisasi. Jika kode ini baru, pertimbangkan untuk mengubah antarmuka publik. Contoh di atas dapat diperbarui sebagai berikut:
public class Person
{
public Person(string first, string last)
{
FirstName = first;
LastName = last;
}
public string FirstName { get; set; }
public string LastName { get; set; }
}
Jika Anda memerlukan pembuatan objek Person
sebelum mengatur nama, Anda dapat menginisialisasi properti menggunakan nilai tidak-null default:
public class Person
{
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
}
Alternatif lain yang mungkin adalah mengubah anggota tersebut menjadi jenis referensi yang dapat diubah ke null. Kelas Person
dapat didefinisikan sebagai berikut jika null
harus diizinkan untuk nama:
public class Person
{
public string? FirstName { get; set; }
public string? LastName { get; set; }
}
Kode yang ada mungkin memerlukan perubahan lain untuk menginformasikan kompilator tentang semantik null untuk anggota tersebut. Anda mungkin telah membuat beberapa konstruktor, dan kelas Anda mungkin memiliki metode pembantu privat yang menginisialisasi satu atau beberapa anggota. Anda dapat memindahkan kode inisialisasi ke dalam satu konstruktor dan memastikan semua konstruktor memanggil konstruktor dengan kode inisialisasi umum. Atau, Anda dapat menggunakan atribut System.Diagnostics.CodeAnalysis.MemberNotNullAttribute dan System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute. Atribut ini menginformasikan kompilator bahwa anggota tidak null setelah metode dipanggil. 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";
}
}
Terakhir, Anda dapat menggunakan operator pengampunan null untuk menunjukkan bahwa anggota diinisialisasi di kode lain. Untuk contoh lain, pertimbangkan kelas berikut yang mewakili model Entity Framework Core:
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
public class TodoContext : DbContext
{
public TodoContext(DbContextOptions<TodoContext> options)
: base(options)
{
}
public DbSet<TodoItem> TodoItems { get; set; } = null!;
}
Properti DbSet
diinisialisasi ke null!
. Itu memberi tahu kompilator bahwa properti diatur ke nilai tidak null. Bahkan, DbContext
dasar melakukan inisialisasi set. Analisis statis kompilator tidak mengambilnya. Untuk informasi selengkapnya tentang bekerja dengan jenis referensi yang dapat diubah ke null dan Entity Framework Core, lihat artikel tentang Bekerja dengan Jenis Referensi yang Dapat Diubah ke Null di EF Core.
Memperbaiki peringatan untuk tidak menginisialisasi anggota yang tidak dapat diubah ke null melibatkan salah satu dari empat teknik:
- Ubah konstruktor atau penginisialisasi bidang untuk memastikan semua anggota yang tidak dapat diubah ke null diinisialisasi.
- Ubah satu atau beberapa anggota menjadi jenis yang dapat diubah ke null.
- Anotasi metode pembantu apa pun untuk menunjukkan anggota mana yang ditetapkan.
- Tambahkan penginisialisasi ke
null!
untuk menunjukkan bahwa anggota diinisialisasi dalam kode lain.
Ketidakcocokan dalam deklarasi kemampuan untuk dapat diubah ke null
Banyak peringatan menunjukkan ketidakcocokan nullability antara tanda tangan untuk metode, delegasi, atau parameter jenis.
- CS8608 - Nullability jenis referensi dalam jenis tidak cocok dengan anggota yang ditimpa.
- CS8609 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan anggota yang ditimpa.
- CS8610 - Nullability jenis referensi dalam parameter jenis tidak cocok dengan anggota yang ditimpa.
- CS8611 - Nullability jenis referensi dalam parameter jenis tidak cocok dengan deklarasi metode parsial.
- CS8612 - Nullability jenis referensi dalam jenis tidak cocok dengan anggota yang diimplementasikan secara implisit.
- CS8613 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan anggota yang diimplementasikan secara implisit.
- CS8614 - Nullability jenis referensi dalam jenis parameter tidak cocok dengan anggota yang diimplementasikan secara implisit.
- CS8615 - Nullability jenis referensi dalam jenis tidak cocok dengan anggota yang diimplementasikan.
- CS8616 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan anggota yang diimplementasikan.
- CS8617 - Nullability jenis referensi dalam jenis parameter tidak cocok dengan anggota yang diimplementasikan.
- CS8619 - Nullability jenis referensi dalam nilai tidak cocok dengan jenis target.
- Argumen CS8620 - tidak dapat digunakan untuk parameter karena perbedaan dalam nullability jenis referensi.
- CS8621 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan delegasi target (mungkin karena atribut nullability).
- CS8622 - Nullability jenis referensi dalam jenis parameter tidak cocok dengan delegasi target (mungkin karena atribut nullability).
- Argumen CS8624 - tidak dapat digunakan sebagai output karena perbedaan dalam nullability jenis referensi.
- CS8631 - Jenis tidak dapat digunakan sebagai parameter jenis dalam jenis atau metode generik. Nullability dari jenis argumen tidak cocok dengan jenis batasan.
- CS8633 - Nullability dalam batasan untuk parameter jenis metode tidak cocok dengan batasan untuk parameter jenis metode antarmuka. Pertimbangkan untuk menggunakan implementasi antarmuka eksplisit sebagai gantinya.
- CS8634 - Jenis tidak dapat digunakan sebagai parameter jenis dalam jenis atau metode generik. Kemampuan null tipe argumen tidak cocok dengan batasan 'kelas'.
- CS8643 - Nullability jenis referensi dalam penentu antarmuka eksplisit tidak cocok dengan antarmuka yang diterapkan oleh jenis .
- Tipe CS8644 - tidak menerapkan anggota antarmuka. Nullability jenis referensi dalam antarmuka yang diimplementasikan oleh jenis dasar tidak cocok.
- Anggota CS8645 - sudah tercantum dalam daftar antarmuka pada jenis dengan berbagai nullability jenis referensi.
- Deklarasi metode parsial CS8667 - memiliki nullability yang tidak konsisten dalam batasan untuk parameter jenis.
- CS8714 - Jenis tidak dapat digunakan sebagai parameter jenis dalam jenis atau metode generik. Nullability dari jenis argumen tidak cocok dengan batasan 'notnull'.
- CS8764 - Nullability jenis pengembalian tidak cocok dengan anggota yang ditimpa (mungkin karena atribut nullability).
- CS8765 - Nullability jenis parameter tidak cocok dengan anggota yang ditimpa (mungkin karena atribut nullability).
- CS8766 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan anggota yang diimplementasikan secara implisit (mungkin karena atribut nullability).
- CS8767 - Nullability jenis referensi dalam jenis parameter tidak cocok dengan anggota yang diimplementasikan secara implisit (mungkin karena atribut nullability).
- CS8768 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan anggota yang diimplementasikan (mungkin karena atribut nullability).
- CS8769 - Nullability jenis referensi dalam jenis parameter tidak cocok dengan anggota yang diimplementasikan (mungkin karena atribut nullability).
- CS8819 - Nullability jenis referensi dalam jenis pengembalian tidak cocok dengan deklarasi metode parsial.
Kode berikut menunjukkan CS8764:
public class B
{
public virtual string GetMessage(string id) => string.Empty;
}
public class D : B
{
public override string? GetMessage(string? id) => default;
}
Contoh sebelumnya menunjukkan metode virtual
di kelas dasar dan override
dengan kemampuan untuk dapat diubah ke null yang berbeda. Kelas dasar mengembalikan string yang tidak dapat diubah ke null, tetapi kelas turunan mengembalikan string yang dapat diubah ke null. Jika string
dan string?
dibalik, itu diizinkan karena kelas turunan lebih ketat. Demikian pula, deklarasi parameter harus cocok. Parameter dalam metode ambil alih dapat mengizinkan null bahkan ketika kelas dasar tidak.
Situasi lain dapat menghasilkan peringatan ini. Anda mungkin memiliki ketidakcocokan dalam deklarasi metode antarmuka dan implementasi metode tersebut. Atau jenis delegasi dan ekspresi untuk delegasi tersebut mungkin berbeda. Parameter jenis dan argumen jenis mungkin berbeda dalam kemampuan untuk dapat diubah ke null.
Untuk memperbaiki peringatan ini, perbarui deklarasi yang sesuai.
Kode tidak cocok dengan deklarasi atribut
Bagian sebelumnya telah membahas bagaimana Anda dapat menggunakan Atribut untuk analisis statis yang dapat diubah ke null untuk menginformasikan kompilator tentang semantik null dari kode Anda. Pengkompilasi memperingatkan Anda jika kode tidak mematuhi janji atribut tersebut:
- CS8607 - Nilai null yang mungkin tidak digunakan untuk jenis yang ditandai dengan
[NotNull]
atau[DisallowNull]
- Metode CS8763 - A yang ditandai
[DoesNotReturn]
tidak boleh dikembalikan. - Metode CS8770 - tidak memiliki
[DoesNotReturn]
anotasi agar sesuai dengan anggota yang diimplementasikan atau ditimpa. - Anggota CS8774 - harus memiliki nilai non-null saat keluar.
- Anggota CS8775 - harus memiliki nilai non-null saat keluar.
- Anggota CS8776 - tidak dapat digunakan dalam atribut ini.
- Parameter CS8777 - harus memiliki nilai non-null saat keluar.
- Parameter CS8824 - harus memiliki nilai non-null saat keluar karena parameter non-null.
- Nilai CS8825 - Return harus non-null karena parameter non-null.
Pertimbangkan kode berikut:
public bool TryGetMessage(int id, [NotNullWhen(true)] out string? message)
{
message = null;
return true;
}
Pengkompilasi menghasilkan peringatan karena message
parameter ditetapkan null
dan metode mengembalikan true
. Atribut NotNullWhen
menunjukkan bahwa hal tersebut seharusnya tidak terjadi.
Untuk mengatasi peringatan ini, perbarui kode Anda sehingga sesuai dengan ekspektasi atribut yang telah diterapkan. Anda dapat mengubah atribut, atau algoritmanya.
Ekspresi sakelar lengkap
Ekspresi pengalihan harus lengkap, yang berarti bahwa semua nilai input harus ditangani. Bahkan untuk jenis referensi yang tidak dapat diubah ke null, null
nilai harus dipertanggungjawabkan. Pengkompilasi mengeluarkan peringatan ketika nilai null tidak ditangani:
- CS8655 - Ekspresi pengalihan tidak menangani beberapa input null (tidak lengkap).
- CS8847 - Ekspresi pengalihan tidak menangani beberapa input null (tidak lengkap). Namun, pola dengan klausa 'kapan' mungkin berhasil mencocokkan nilai ini.
Contoh kode berikut menunjukkan kondisi ini:
int AsScale(string status) =>
status switch
{
"Red" => 0,
"Yellow" => 5,
"Green" => 10,
{ } => -1
};
Ekspresi input adalah string
, bukan string?
. Pengkompilasi masih menghasilkan peringatan ini. Pola { }
menangani semua nilai non-null, tetapi tidak cocok null
dengan . Untuk mengatasi kesalahan ini, Anda dapat menambahkan kasus eksplisit null
, atau mengganti { }
dengan _
pola (buang). Pola buang cocok null serta nilai lainnya.