Mengenai pesan pengecualian tidak tertangani .NET ini:
Referensi objek tidak disetel ke contoh objek.
Mengapa NET tidak menunjukkan objek mana null
?
Saya tahu bahwa saya dapat memeriksa null
dan mengatasi kesalahan tersebut. Namun, mengapa NET tidak membantu menunjukkan objek mana yang memiliki referensi null dan ekspresi mana yang memicu NullReferenceException
?
Jawaban:
(Untuk informasi tentang pembantu pengecualian baru di Visual Studio 2017 lihat akhir jawaban ini)
Pertimbangkan kode ini:
Ini akan membuang
NullReferenceException
di baris kedua dan Anda ingin tahu mengapa .NET tidak memberi tahu Anda bahwa itus
adalah nol ketika pengecualian dilemparkan.Untuk memahami mengapa Anda tidak mendapatkan informasi itu, Anda harus ingat bahwa itu bukan C # source yang mengeksekusi melainkan IL:
Ini adalah
callvirt
opcode yang melemparNullReferenceException
dan melakukan itu ketika argumen pertama pada tumpukan evaluasi adalah referensi nol (yang dimuat menggunakanldloc.0
).Jika .NET harus dapat mengetahui bahwa itu adalah
s
referensi null, itu harus dalam beberapa cara melacak bahwa argumen pertama pada tumpukan evaluasi berasal dari formulirs
. Dalam hal ini mudah bagi kita untuk melihat bahwa itu adalahs
nol tetapi bagaimana jika nilainya adalah nilai yang dikembalikan dari pemanggilan fungsi lain dan tidak disimpan dalam variabel apa pun? Bagaimanapun, jenis informasi ini bukanlah yang ingin Anda lacak di mesin virtual seperti mesin virtual .NET.Untuk menghindari masalah ini, saya sarankan Anda melakukan pemeriksaan argumen null di semua panggilan metode publik (kecuali tentu saja Anda mengizinkan referensi null):
Jika null dilewatkan ke metode Anda mendapatkan pengecualian yang secara tepat menjelaskan apa masalahnya (yaitu
s
null).Empat tahun kemudian Visual Studio 2017 sekarang memiliki pembantu pengecualian baru yang akan mencoba untuk memberitahu apa yang null ketika
NullReferenceException
dilempar. Ia bahkan dapat memberi Anda informasi yang diperlukan jika itu adalah nilai kembalian dari metode yang nol:Perhatikan bahwa ini hanya berfungsi dalam build DEBUG.
sumber
null
.null
- perhatikan bahwa OP tidak mengklaim dia ingin tahu bahwa untuk rilis build, juga, build debug mungkin sudah cukup.null
) dengan baris dan kolom file sumber yang mengembalikan referensi objek tersebut.Seperti apa tampilan pesan kesalahan yang Anda inginkan dalam kasus berikut ini?
Tidak ada nama variabel untuk dilaporkan di sini!
sumber
Object reference obtained from AnyObject.GetANullObject() not set to an instance of an object.
pesan kesalahan.Nah, itu terserah insinyur di Microsoft untuk menjawab. Tapi Anda jelas dapat menggunakan debugger dan menambahkan jam tangan untuk mencari tahu mana yang bermasalah.
Namun, pengecualiannya
NullReferenceException
berarti referensi tersebut tidak ada . Anda tidak bisa mendapatkan objek yang belum dibuat sama sekali.but why .NET don't tell us which object is null?
Karena tidak tahu objek mana yang nol. Objeknya sama sekali tidak ada!Sama halnya ketika saya mengatakan, C # dikompilasi ke kode .NET IL. Kode .NET IL tidak mengetahui nama atau ekspresi. Ia hanya mengetahui referensi dan lokasinya. Di sini juga, Anda tidak bisa mendapatkan apa yang tidak ada. Ekspresi atau nama variabel tidak ada.
Filosofi: Anda tidak dapat membuat telur dadar jika Anda tidak memiliki telur.
sumber
Tidak yakin, tetapi ini mungkin karena .Net tidak tahu apakah itu kelas yang ditentukan sebelumnya atau ditentukan pengguna. Jika sudah ditentukan sebelumnya maka bisa nihil (seperti string yang menempati 2 Bytes) tetapi jika itu ditentukan oleh pengguna daripada kita harus membuat turunannya sehingga tahu bahwa objek ini akan menempati banyak memori ini. Jadi karena itu melempar kesalahan pada saat run-time.
sumber
Pertanyaan bagus. Kotak pesan tidak berguna. Bahkan jika itu terkubur satu mil jauhnya dari definisi referensi, beberapa kelas atau perakitan atau file atau informasi lain akan lebih baik daripada yang mereka sediakan saat ini (baca: lebih baik daripada tidak sama sekali).
Pilihan terbaik Anda adalah menjalankannya di debugger dengan informasi debug, dan IDE Anda akan berhenti di baris yang menyinggung (cukup jelas menunjukkan bahwa informasi yang berguna sebenarnya tersedia).
sumber