Pertimbangkan kode berikut:
#nullable enable
class Foo
{
public string? Name { get; set; }
public bool HasName => Name != null;
public void NameToUpperCase()
{
if (HasName)
{
Name = Name.ToUpper();
}
}
}
Pada Name = Name.ToUpper () saya mendapat peringatan bahwa Name adalah referensi nol, yang jelas salah. Saya bisa menyembuhkan peringatan ini dengan memasukkan HasName sehingga kondisinya adalah jika (Nama! = Null).
Apakah ada cara saya bisa menginstruksikan kompiler bahwa tanggapan sebenarnya dari HasName menyiratkan kendala non-nullability pada Nama?
Ini penting karena HasName mungkin sebenarnya menguji lebih banyak hal, dan saya mungkin ingin menggunakannya di beberapa tempat, atau mungkin menjadi bagian publik dari permukaan API. Ada banyak alasan untuk ingin memasukkan cek nol ke dalam metode itu sendiri, tetapi hal itu tampaknya mematahkan pemeriksa referensi nullable.
c#
nullable-reference-types
John Melville
sumber
sumber
HasValue
pada jenis yang dapat dibatalkan, bukan mengeceknyanull
. Ini mungkin tidak mempengaruhi masalah Anda.#nullable disable
itu#nullable enable
ataurestore
lagi sesudahnya ( docs.microsoft.com/en-us/dotnet/csharp/… ).!
operator "sialan" .if(HasName) { Name = Name!.ToUpper(); }
Jawaban:
Saya melihat-lihat atribut yang berbeda dari
System.Diagnostics.CodeAnalysis
dan saya tidak dapat menemukan sesuatu yang berlaku, yang sangat mengecewakan. Tampaknya yang paling dekat dengan apa yang Anda inginkan adalah:Kelihatannya cukup rumit, saya tahu. Anda dapat melihat pada dokumen MSDN untuk atribut yang dapat dibatalkan , mungkin Anda akan menemukan sesuatu yang lebih rapi.
sumber
if(Name != null) return Null.ToUpper()
, tidak akan ada peringatan untuk dereferensi nol, meskipun secara teknis itu adalah kondisi lomba TOCTOU. Saya ingat Mads Torgersen berbicara tentang bagaimana mereka menganggap itu, tetapi itu akan menghasilkan begitu banyak kesalahan positif sehingga seluruh fitur tipe referensi yang dapat dibatalkan akan sia-sia - 99% dari waktu properti Anda tidak akan diubah oleh utas lainnya. Jadi yang perlu Anda lakukan adalah membuat atribut yang akan membuat pemeriksaan pada properti ini diperlakukan sebagai cek untuk null pada properti lain.String adalah tipe referensi, dan nullable (misalnya
int?
) adalah tipe nilai nullable. Jadi Anda tidak bisa melakukan inistring? myString
; Yang Anda butuhkan adalah ini:sumber