Kami meluncurkan sistem, dan terkadang kami mendapatkan pengecualian yang terkenal NullReferenceException
dengan pesannya Object reference not set to an instance of an object
.
Namun, dalam metode di mana kita memiliki hampir 20 objek, memiliki log yang mengatakan objek adalah null, benar-benar tidak berguna sama sekali. Ini seperti memberi tahu Anda, ketika Anda adalah agen keamanan sebuah seminar, bahwa seorang pria di antara 100 hadirin adalah seorang teroris. Itu benar-benar tidak berguna sama sekali bagi Anda. Anda harus mendapatkan informasi lebih lanjut, jika Anda ingin mendeteksi pria mana yang merupakan pria yang mengancam.
Demikian juga, jika kita ingin menghapus bug, kita perlu tahu objek mana yang null.
Sekarang, sesuatu telah terobsesi dengan pikiran saya selama beberapa bulan, dan itu adalah:
Mengapa .NET tidak memberi kami nama, atau setidaknya jenis referensi objek, yang nol?. Tidak bisakah ia memahami tipe dari refleksi atau sumber lain?
Juga, apa praktik terbaik untuk memahami objek mana yang nol? Haruskah kita selalu menguji nullability objek dalam konteks ini secara manual dan mencatat hasilnya? Apakah ada cara yang lebih baik?
Pembaruan:
Pengecualian The system cannot find the file specified
memiliki sifat yang sama. Anda tidak dapat menemukan file mana, sampai Anda melampirkan ke proses dan debug. Saya kira jenis pengecualian ini bisa menjadi lebih cerdas. Bukankah lebih baik jika .NET dapat memberi tahu kami c:\temp.txt doesn't exist.
alih-alih pesan umum itu? Sebagai pengembang, saya memilih ya.
sumber
new
untuk membuat instance kelas. Kapan petunjuk semacam itu benar-benar membantu?Jawaban:
Pada
NullReferenceException
dasarnya memberitahu Anda: Anda salah melakukannya. Tidak lebih, tidak kurang. Sebaliknya, itu bukan alat debugging lengkap. Dalam hal ini saya katakan Anda salah melakukannya karena keduanyaSaya penggemar berat memeriksa semuanya sebelum segala sesuatunya mulai salah, dan memberikan informasi yang baik kepada pengembang. Singkatnya: tulis cek menggunakan
ArgumentNullException
dan suka dan tulis nama sendiri. Berikut ini contohnya:Anda juga dapat melihat Kontrak Kode , memiliki kebiasaan tetapi berfungsi dengan baik dan menghemat beberapa mengetik.
sumber
I only say that checking every object to get sure that it's not null, is not a good method
Serius. Ini metode terbaik. Dan bukan hanya nol, periksa setiap argumen untuk nilai yang masuk akal. Semakin awal Anda menangkap kesalahan, semakin mudah untuk menemukan penyebabnya. Anda tidak ingin harus melacak beberapa tingkat dalam jejak tumpukan untuk menemukan panggilan yang menyebabkannya.Itu benar-benar harus menunjukkan dengan tepat apa yang Anda coba panggil. Itu seperti mengatakan "Ada masalah. Kamu harus memperbaikinya. Aku tahu apa itu. Aku tidak akan memberitahumu. Kamu mencari tahu" Agak seperti setengah jawaban pada Stack Overflow ini, ironisnya.
Jadi seberapa bermanfaatkah itu, misalnya, jika Anda mendapatkan ini ...
...? Harus masuk ke dalam kode, melangkah melaluinya, dan mencari tahu bahwa hal yang Anda coba panggil
null
baik-baik saja, tetapi mengapa tidak memberi kami sedikit bantuan?Saya setuju bahwa biasanya berguna untuk menelusuri kode untuk mendapatkan jawaban (karena Anda mungkin akan menemukan lebih banyak), tetapi sering kali banyak waktu dan frustrasi akan disimpan jika
NullReferenceException
teksnya lebih seperti contoh di atas.Katakan saja.
sumber
KeyNotFoundException
dan banyak gangguan lainnya ...Log Anda harus menyertakan jejak stack - yang biasanya memberi Anda petunjuk tentang baris mana dalam metode yang memiliki masalah. Anda mungkin perlu membuat versi rilis Anda menyertakan simbol PDB sehingga Anda memiliki ide untuk baris mana kesalahan tersebut aktif.
Memang, itu tidak akan membantu Anda dalam hal ini:
Prinsip tell don't ask dapat membantu menghindari kode tersebut.
Mengenai mengapa informasi tersebut tidak termasuk, saya tidak yakin - Saya menduga bahwa setidaknya dalam membangun debug, jika mereka benar-benar ingin, mereka bisa mengetahuinya. Mengambil crash dump dan membuka di WinDBG dapat membantu.
sumber
Pengecualian telah dibuat sebagai alat untuk menandai kondisi non-fatal yang luar biasa di rantai panggilan. Artinya, mereka tidak dirancang sebagai alat debugging.
Jika pengecualian null-pointer adalah alat debugging, itu akan membatalkan eksekusi program tepat di tempat, memungkinkan debugger untuk terhubung, mengarahkannya tepat di garis yang memberatkan. Ini akan memberi programmer semua informasi konteks yang tersedia. (Yang cukup banyak seperti Segfault karena akses pointer nol tidak dalam C, meskipun agak kasar.)
Namun, pengecualian null-pointer dirancang sebagai kondisi runtime yang valid yang dapat dibuang dan ditangkap dalam aliran program normal. Konsekuensinya, pertimbangan kinerja perlu diperhitungkan. Dan setiap kustomisasi pesan pengecualian membutuhkan objek string yang dibuat, digabungkan, dan dihancurkan saat runtime. Dengan demikian, pesan statis tidak dapat disangkal lebih cepat.
Saya tidak mengatakan bahwa runtime tidak dapat diprogram dengan cara yang akan menghasilkan nama referensi yang memberatkan. Itu bisa dilakukan. Itu hanya akan membuat pengecualian lebih lambat dari mereka. Jika ada yang cukup peduli, fitur semacam itu bahkan dapat dibuat dapat dipindah-pindah, sehingga tidak akan memperlambat kode produksi, tetapi memungkinkan proses debug yang lebih mudah; tetapi karena alasan tertentu tampaknya tidak ada yang cukup peduli.
sumber
Cromulent mengenai kuku di kepala saya pikir, namun ada poin yang jelas juga bahwa jika Anda mendapatkan
NullReferenceException
Anda memiliki variabel yang tidak diinisialisasi. Argumen bahwa Anda memiliki sekitar 20 objek yang diteruskan ke dalam metode tidak dapat dikatakan sebagai mitigasi: sebagai pencipta sejumlah kode Anda harus bertanggung jawab atas tindakannya, yang mencakup kepatuhannya pada seluruh basis kode, karena pemanfaatan variabel yang tepat dan benar, dll.itu berat, membosankan dan kadang-kadang membosankan, tetapi hasilnya pada akhirnya sepadan: banyak kali ketika saya harus menjelajah melalui file log dengan berat beberapa gigabyte, dan mereka hampir selalu membantu. Namun sebelum Anda sampai ke tahap itu, debugger dapat membantu Anda, dan sebelum tahap perencanaan yang baik akan menghemat banyak rasa sakit (dan saya tidak bermaksud pendekatan rekayasa penuh untuk Anda solusi kode baik: sketsa sederhana dan beberapa catatan dapat dan akan lebih baik daripada tidak sama sekali).
Berkenaan dengan
Object reference not set to an instance of an object
kode tidak dapat menebak nilai-nilai yang kita sukai: itu adalah tugas kami sebagai programmer, dan itu berarti Anda telah melewati variabel yang tidak diinisialisasi.sumber
Pelajari cara menggunakan debugger. Ini persis seperti apa itu dirancang untuk. Tetapkan titik istirahat pada metode yang dimaksud dan pergilah.
Cukup langkah melalui kode Anda dan lihat apa nilai semua variabel Anda pada titik-titik tertentu.
Sunting: Terus terang saya terkejut bahwa belum ada orang lain yang menyebutkan menggunakan debugger.
sumber
Jika Anda ingin menggunakan jawaban @ stijn dan memberikan cek nol pada kode Anda, cuplikan kode ini akan membantu. Berikut ini beberapa info tentang cuplikan kode . Setelah Anda mengatur ini, cukup ketik
argnull
, tekan tab dua kali, dan kemudian isi yang kosong.sumber
nameof
jadi snippet Anda bisa jadithrow new ArgumentNullException(nameof($argument$))
yang memiliki keuntungan tidak termasuk konstanta sihir, diperiksa oleh kompiler, dan bekerja lebih baik dengan alat refactoring