Saya ingin mencegah pemrosesan lebih lanjut pada objek jika itu nol.
Dalam kode berikut ini saya memeriksa apakah objek tersebut null oleh:
if (!data.Equals(null))
dan
if (data != null)
Namun, saya menerima NullReferenceException
di dataList.Add(data)
. Jika objek itu nol, seharusnya tidak pernah masukif
pernyataan!
Jadi, saya bertanya apakah ini cara yang tepat untuk memeriksa apakah suatu objek adalah nol:
public List<Object> dataList;
public bool AddData(ref Object data)
bool success = false;
try
{
// I've also used "if (data != null)" which hasn't worked either
if (!data.Equals(null))
{
//NullReferenceException occurs here ...
dataList.Add(data);
success = doOtherStuff(data);
}
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
return success;
}
Jika ini adalah cara yang tepat untuk memeriksa apakah objek tersebut null, apa yang saya lakukan salah (bagaimana saya bisa mencegah pemrosesan lebih lanjut pada objek untuk menghindari NullReferenceException)?
c#
null
nullreferenceexception
pengembang
sumber
sumber
throw e;
versusthrow new Exception(e.ToString());
!= null
cek nol Anda..Equals
akan selalu melempar eksepsi jika objeknya nol.throw e;
tidak jauh lebih baik.throw;
, di sisi lain ...e.ToString()
akan menghasilkan string yang tidak hanya mencakup pesan kesalahan, tetapi juga semuaInnerExceptions
dan jejak stack. Jadi itu semacam pesan pengecualian yang sangat berat. Jika Anda (benar!) Ingin menyimpan informasi ini, dan tetap di tempatnya, gunakan sajathrow;
.Jawaban:
Bukan
data
itunull
, tapidataList
.Anda harus membuatnya dengan
Bahkan lebih baik: karena ini adalah ladang, buatlah itu
private
. Dan jika tidak ada yang menghalangi Anda, lakukan jugareadonly
. Latihan yang bagus.Ke samping
Cara yang benar untuk memeriksa nullity adalah
if(data != null)
. Cek semacam ini ada di mana-mana untuk jenis referensi; bahkanNullable<T>
mengesampingkan operator kesetaraan menjadi cara yang lebih nyaman untuk mengekspresikannullable.HasValue
ketika memeriksa nullity.Jika Anda melakukannya
if(!data.Equals(null))
maka Anda akan mendapatkanNullReferenceException
ifdata == null
. Yang agak lucu karena menghindari pengecualian ini adalah tujuan di tempat pertama.Anda juga melakukan ini:
Ini jelas tidak baik. Saya bisa membayangkan bahwa Anda meletakkannya di sana supaya Anda bisa masuk ke debugger saat masih di dalam metode, dalam hal ini abaikan paragraf ini. Kalau tidak, jangan menangkap pengecualian untuk apa pun. Dan jika Anda melakukannya, rethrow mereka hanya menggunakan
throw;
.sumber
null != data
. Menempatkan konstanta pertama-tama mengubah kesalahan ketik boneheadnull = data
menjadi kesalahan kompiler, bukan tugas yang tidak disengaja. (Juga berfungsi untuk==
.)if (data = null)
sudah ada kesalahan waktu kompilasi, jadi walaupun butuh beberapa dekade untuk sampai di sana, kita tidak perlu benar-benar waspada lagi. Bahkan kompiler C ++ akan dengan mudah menghasilkan peringatan tentang kemungkinan tugas yang tidak diinginkan untuk kode itu.dalam penggunaan C #> 7.0
if (obj is null)
...Ini akan mengabaikan == atau! = Yang ditentukan oleh objek (kecuali tentu saja Anda ingin menggunakannya ...)
Untuk tidak menggunakan nol
if (obj is object)
(atauif (!(obj is null))
)sumber
obj is not null
)if (obj aint null)
:(if (obj is object)
C # 6 memiliki pemeriksaan null monadik :)
sebelum:
setelah:
sumber
result = myObject == null ? null : myObject.SomeProperty
dan contoh Anda memberi saya tip untuk menulisresult = myObject?.SomeProperty
. Pria!! Itu licik. Saya masih suka coding ...DataList Anda adalah nol karena belum dibuat, dilihat dari kode yang telah Anda posting.
Mencoba:
}
sumber
[Diedit untuk mencerminkan petunjuk oleh @ kelton52]
Cara termudah adalah melakukan
object.ReferenceEquals(null, data)
Karena
(null==data)
TIDAK dijamin bekerja:Menghasilkan:
sumber
Tidak, Anda harus menggunakan
!=
. Jikadata
sebenarnya nol maka program Anda hanya akan crash denganNullReferenceException
sebagai akibat dari mencoba memanggilEquals
metodenull
. Sadari juga bahwa, jika Anda secara khusus ingin memeriksa kesetaraan referensi, Anda harus menggunakanObject.ReferenceEquals
metode ini karena Anda tidak pernah tahu bagaimanaEquals
penerapannya.Program Anda macet karena
dataList
batal karena Anda tidak pernah menginisialisasi.sumber
Masalah dalam hal ini bukan itu
data
nol. ItudataList
sendiri adalah nol.Di tempat Anda mendeklarasikan
dataList
Anda harus membuatList
objek baru dan menetapkannya ke variabel.sumber
Selain jawaban @Jose Ortega , lebih baik menggunakan metode ekstensi
Dan gunakan
IsNull
metode untuk semua objek seperti:sumber
return T == null ? true : false;
dan tidak adilreturn T == null;
?Pada C # 8 Anda dapat menggunakan pola properti 'kosong' (dengan pencocokan pola ) untuk memastikan objek tidak nol:
Pendekatan ini berarti " jika objek referensi instance dari sesuatu " (yaitu itu bukan nol).
Anda dapat menganggap ini sebagai kebalikan dari:
if (obj is null)...
. yang akan mengembalikan true ketika objek tidak merujuk instance dari sesuatu.Untuk info lebih lanjut tentang pola dalam C # 8.0 baca di sini .
sumber
Pada C # 9 yang dapat Anda lakukan
Untuk tidak menggunakan nol
Jika Anda perlu menimpa penggunaan perilaku ini
==
dan!=
sesuai.sumber
Jeffrey L Whitledge benar. Obyek `dataList´ Anda sendiri adalah nol.
Ada juga masalah lain dengan kode Anda: Anda menggunakan kata kunci ref, yang berarti data argumen tidak boleh nol! MSDN mengatakan:
Ini juga bukan ide yang baik untuk menggunakan obat generik dengan tipe `Object`. Generik harus menghindari tinju / unboxing dan juga memastikan keamanan jenis. Jika Anda ingin jenis yang umum buat metode Anda menjadi umum. Akhirnya kode Anda akan terlihat seperti ini:
sumber
Seperti orang lain telah menunjukkan, itu bukan
data
melainkan kemungkinandataList
yangnull
. Selain itu...catch
-throw
Adalah antipattern yang hampir selalu membuat saya ingin muntah setiap kali melihatnya. Bayangkan bahwa ada sesuatu yang salah di dalam sesuatu yangdoOtherStuff()
memanggil. Yang Anda dapatkan hanyalah sebuahException
benda, dilemparkan kethrow
dalamAddData()
. Tidak ada jejak stack, tidak ada informasi panggilan, tidak ada keadaan, tidak ada sama sekali untuk menunjukkan sumber sebenarnya dari masalah, kecuali jika Anda masuk dan beralih debugger Anda untuk istirahat dengan pengecualian dilemparkan daripada pengecualian tidak ditangani. Jika Anda menangkap pengecualian dan hanya melemparkannya kembali dengan cara apa pun , terutama jika kode di blok percobaan sama sekali nontrivial, bantulah diri Anda sendiri (dan kolega Anda, saat ini dan di masa depan) dan buang seluruhtry
-catch
blok . Memang,throw;
lebih baik daripada alternatif, tetapi Anda masih memberi diri Anda (atau siapa pun yang mencoba untuk memperbaiki bug dalam kode) benar-benar tidak perlu sakit kepala. Ini bukan untuk mengatakan bahwa coba-tangkap-lempar tentu jahat, asalkan Anda melakukan sesuatu yang relevan dengan objek pengecualian yang dilemparkan ke dalam blok tangkap.Lalu ada potensi masalah penangkapan
Exception
di tempat pertama, tapi itu masalah lain, terutama karena dalam kasus khusus ini Anda melempar pengecualian.Hal lain yang menurut saya lebih dari sedikit berbahaya adalah yang
data
berpotensi mengubah nilai selama pelaksanaan fungsi, karena Anda melewati referensi. Jadi cek nol mungkin lulus tetapi sebelum kode melakukan sesuatu dengan nilainya, itu berubah - mungkin kenull
. Saya tidak yakin apakah ini masalah atau tidak (mungkin tidak), tetapi tampaknya patut diwaspadai.sumber
menggunakan:
Penggunaan bersyarat:
Pembaruan (dengan cara lain) diperbarui pada tanggal 08/31/2017. Terima kasih atas komentarnya.
sumber
cond ? true : false;
sepenuhnya sama dengan adilcond
. Ini tidak menambah apa pun.return T == null;
juga mengembalikan boolean!return T == null ? true : false;
hanya digunakanreturn T == null;
.Setiap kali Anda membuat objek kelas Anda harus memeriksa apakah objek tersebut null atau tidak menggunakan kode di bawah ini.
Contoh: object1 adalah objek kelas
sumber
Saya hanya mengikuti metode yang biasanya kita ikuti dalam java script. Untuk mengonversi objek menjadi string, lalu periksa apakah itu nol.
sumber
Saya melakukan lebih sederhana (cara positif) dan sepertinya bekerja dengan baik.
Karena segala jenis "objek" setidaknya merupakan objek
sumber