Apa perbedaan antara mendeklarasikan kelas null dan membuat instance kelas?

Saya tidak yakin apakah pertanyaan saya masuk akal. Tapi saya hanya ingin tahu apakah ada perbedaan antara dua baris kode ini:

Dictionary<int, List<string>> myDictionary = new Dictionary<int, List<string>>();

vs

Dictionary<int, List<string>> myDictionary = null;

Saya tahu baris pertama membuat objek kamus baru tetapi karena saya belum menambahkan apa pun ke dalam kamus, itu hanya objek kosong. Baris kedua hanyalah objek kamus kosong. Apakah ada perbedaan?


person d1du    schedule 11.07.2016    source sumber
comment
Anda bisa menggunakan debugger dan mencari tahu sendiri?!?   -  person Uwe Keim    schedule 11.07.2016
comment
Null menunjuk ke tidak ada objek. Di sini kita melihat beberapa informasi dan fakta tentang literal nol (null). Null diwakili oleh nilai 0, tetapi Anda tidak dapat menggunakan 0 sebagai ganti null dalam program Anda. Null menyebabkan banyak pengecualian.   -  person Gehan Fernando    schedule 11.07.2016
comment
Coba hubungi .Count pada keduanya - Anda akan segera melihat perbedaannya!   -  person CompuChip    schedule 11.07.2016
comment
Kemungkinan duplikat Apa itu null di Java? ATAU Apa itu null di c#, java?   -  person Draken    schedule 11.07.2016
comment
Terima kasih atas semua tanggapan nontroll. Para downvoter, dapatkan lyfe pl0x.   -  person d1du    schedule 08.10.2016


Jawaban (6)


Dalam kasus pertama:

     Dictionary<int, List<string>> myDictionary = new Dictionary<int, List<string>>();
     myDictionary.Add(key,value); // NOT throw null reference exception.

Dalam kasus kedua:

     Dictionary<int, List<string>> myDictionary = null;
     myDictionary.Add(key,value); // will throw null reference exception.

Untuk menggunakan objek koleksi apa pun, Anda harus membuat placeholder terlebih dahulu.

person Gaurava Agarwal    schedule 11.07.2016
comment
Saya sarankan Anda mengubah contoh Anda menjadi contoh yang dapat dikompilasi - dan menggunakan terminologi C# daripada terminologi Java (pengecualian referensi nol, bukan pengecualian pointer nol) - person Jon Skeet; 11.07.2016

Anggap saja sebagai berikut:

Variabelnya adalah kertas kosong. Anda boleh atau tidak boleh menulis alamat di sana yang mengarahkan Anda ke suatu lokasi.

Baris pertama menulis di kertas alamat objek (dibuat setelah kata kunci baru).

Pada baris kedua, Anda hanya memiliki kertas kosong yang diharapkan (oleh kompiler) untuk menyimpan referensi kamus di beberapa titik, tetapi saat ini hanya kertas kosong. Jadi jika Anda mencoba menggunakannya untuk menuju ke alamat kamus, Anda tidak bisa (alias NullReferenceException). Tidak ada informasi dimana benda tersebut berada (sebenarnya tidak ada alamatnya).

Dalam kode:

Dictionary<int, List<string>> myDictionary = new Dictionary<int, List<string>>();
myDictionary.Add(1, "1"); // OK, myDictionary points to an address of
                         // Dictionary object and I can access it.

Ketika:

Dictionary<int, List<string>> myDictionary = null;
myDictionary.Add(1, "1");  // Fails at run-time, I have no address for a Dictionary object 
                           // here AKA : NullReferenceException

Pernyataan salah yang Anda katakan:

Anda tidak mendeklarasikan kelas null seperti yang Anda katakan, Anda membuat variabel yang menunjuk ke null.

Baris kedua bukanlah objek kamus kosong seperti yang Anda katakan. Ini adalah variabel bertipe Kamus yang menunjuk ke NULL. Tidak ada objek kamus kosong di memori.

person Zein Makki    schedule 11.07.2016

Baris pertama sebenarnya membuat objek (memori dialokasikan); ini berarti Anda memiliki sesuatu untuk dirujuk dan ditindaklanjuti (misalnya, myDictionary.Count() akan menghasilkan 0). Kode if (null == myDictionary) akan bernilai false.

Baris kedua tidak membuat objek; Anda tidak memiliki referensi apa pun (dan dalam hal ini, memanggil myDictionary.Count() akan mengakibatkan NullReferenceException dilempar). Kode if (null == myDictionary) akan bernilai true.

person Jacob Pitts    schedule 11.07.2016
comment
Bukan berarti Anda akan menggunakan Kondisi Yoda di C#, biasanya... - person Jon Skeet; 11.07.2016
comment
@Jon kebiasaan lama sulit dihilangkan :) - person Jacob Pitts; 11.07.2016

Baris kedua bukanlah objek kamus kosong. Coba tambahkan sesuatu ke objek kamus ke-2 untuk mencari tahu sendiri. Umumnya Anda mengarahkan referensi ke null ketika Anda benar-benar ingin menetapkan objek ke referensi itu nanti di program.

person Geek    schedule 11.07.2016

Jawaban Sederhana, Kasus pertama Anda dapat menggunakannya, Kasus kedua akan memberi Anda NullReferenceException saat Anda melanjutkan dengan itu, Karena null berarti tidak ada Jadi Anda tidak dapat mengaksesnya sampai dipakai.

Tidak ada yang salah dengan deklarasi kedua, tetapi Jika Anda ingin menggunakan ini berarti Anda perlu membuat instance-nya (sebelum digunakan), Jika tidak maka akan Melempar NullReferenceException. Misalkan PopulateDictonary() akan menjadi metode yang akan Mengembalikan objek Dictionary maka Anda dapat menggunakan metode ini untuk membuat instance myDictionary.

Itu adalah:

Dictionary<int, List<string>> myDictionary;
// Some code here, Not using myDictionary
myDictionary = PopulateDictonary();

Catatan :- Anda harus memeriksa Null sebelum menggunakan myDictionary jika Anda menggunakan Instantiate objek secara kondisional untuk menghindari Pengecualian.

person sujith karivelil    schedule 11.07.2016
comment
Namanya NullReferenceException. - person Uwe Keim; 11.07.2016
comment
Saya akan menulis hal yang sama. Saya dapat menambahkan jawaban ini bahwa jawaban pertama Anda membuat instance, dan jawaban kedua Anda hanya mendeklarasikannya. Untuk menggunakannya, Anda harus membuat instance, bukan hanya mendeklarasikannya. - person matiaslauriti; 11.07.2016
comment
Ini tidak menjelaskan perbedaannya dengan jelas. Mungkin variabel akan diberi nilai yang berbeda nanti... mungkin akan diberi nilai dengan syarat... dan menggunakan referensi null mungkin baik-baik saja. Misalnya, ini dapat diteruskan sebagai argumen ke metode lain yang dapat menangani nilai parameter null. NullReferenceException hanya akan dilemparkan jika kode mencoba melakukan dereferensi nilainya. - person Jon Skeet; 11.07.2016
comment
@JonSkeet: izinkan saya menjelaskannya - person sujith karivelil; 11.07.2016
comment
Saya akan menghapus apa pun tentang nilai default - itu tidak relevan jika ini adalah deklarasi variabel lokal. Dan sekali lagi, variabel dapat digunakan untuk meneruskan nilai ke sesuatu yang lain, namun tetap memiliki nilai nol. - person Jon Skeet; 11.07.2016
comment
@JonSkeet : terima kasih atas saran dan dukungan yang berharga - person sujith karivelil; 11.07.2016

Ada banyak perbedaan antara kedua pernyataan tersebut, yang paling mendasar: yang pertama adalah inisialisasi sedangkan yang kedua hanyalah sebuah deklarasi. Perhatikan kode berikut:

Base b = new Derived();

Terhadap

Base b = null;

Pada pernyataan pertama Anda membuat instance baru dari Derived dan menetapkan ke b. Biasanya Anda memerlukan turunan kelas untuk memanggil anggotanya (untuk mempermudah kami menghilangkan anggota statis di sini), dalam kasus Anda metode Add yang didefinisikan dalam Dictionary misalnya. Dengan deklarasi Anda cukup mendefinisikan anggota yang dapat Anda panggil pada sebuah instance kelas, namun tidak ada yang disebutkan tentang instance yang Anda panggil anggota tersebut. Jadi pada dasarnya Anda memerlukan dua informasi: kontrak kode yang ditentukan oleh antarmuka (bukan arti OOP) yang Anda gunakan - dalam kasus Anda ini hanya Dictionary<int, List<string>>. Sekarang Anda tahu apa yang dapat Anda lakukan dengan instance kelas ini. Namun Anda tidak memiliki turunan dari kelas tersebut selama Anda menggunakan tugas null. Ini adalah informasi kedua - contoh sebenarnya.

Untuk tetap menggunakan contoh saya sebelumnya, bagaimana seharusnya kompiler mengetahui kelas mana yang sebenarnya gunakan - Base atau Derived. Hal ini tidak serta merta mempengaruhi apa yang dapat Anda lakukan dengan instance tersebut (yang diberikan oleh definisi dalam Base), namun terlebih lagi bagaimana Anda melakukannya karena Derived mungkin memiliki logikanya sendiri untuk melakukan hal-hal yang ditentukan dalam Base.

person HimBromBeere    schedule 11.07.2016