Mengapa operator is return false ketika diberikan null?


136

Menurut saya isoperatornya agak tidak konsisten.

bool Test()
{
    // Returns false, but should return true.
    return null is string;
}

Seseorang mengharapkan bahwa nullnilai tersebut termasuk dalam jenis referensi (atau nullable) apa pun. Dan memang, spesifikasi bahasa C # mengatakan sesuatu yang mendukung hipotesis ini, misalnya (6.1.6 Konversi referensi implisit):

Konversi referensi implisit adalah:
...
• Dari literal nol ke tipe referensi apa pun.

Deskripsi (7.10.10 adalah operator) dari ismulai operator dengan mengatakan bahwa ekspresi (E is T)akan menghasilkan benar ketika konversi referensi dari Eke Tada, tapi kemudian penulis pergi dengan secara eksplisit tidak termasuk kasus ketika Eadalah nullliteral atau memiliki nullnilai .

Mengapa mereka melakukan itu? Bagi saya hal itu tampak berlawanan dengan intuisi.


Mengapa mereka secara eksplisit mengecualikan null adalah pertanyaan terbaik untuk programmer.stackoverflow.com
Variabel Miserable

2
Saya tidak bisa membatalkan pemungutan suara saya, tetapi pertanyaan-pertanyaan ini baik-baik saja di sini: meta.stackexchange.com/questions/36850/…
Merlyn Morgan-Graham

di java null typeof Objectjuga mengembalikan false
ratchet freak

Asumsikan bahwa null is stringdulu true, dan ini tersirat bahwa nulladalah a string. Juga menganggap bahwa null is Nullable<int>adalah true, menyiratkan bahwa nulladalah Nullable<int>. Sekarang, jawab pertanyaan ini: tipe apakah itu null?
pengguna

1
@Michael Kjörling: Non sequitur. Dari fakta yang disebutkan (null adalah string, null adalah Nullable <int>) tidak berarti bahwa saya harus bisa menjawab pertanyaan itu.
Gebb

Jawaban:


195

Pertanyaan ini adalah subjek blog saya pada tanggal 30 Mei 2013 . Terima kasih atas pertanyaan bagusnya!


Anda sedang menatap jalan masuk yang kosong.

Seseorang bertanya kepada Anda, "bisakah jalan masuk Anda menampung Honda Civic?"

Iya. Ya bisa.

Seseorang mengarahkan Anda ke jalan masuk kedua. Itu juga kosong. Mereka bertanya, "Bisakah isi jalan masuk saya saat ini sesuai dengan jalan masuk Anda?"

Ya tentu saja. Kedua jalan masuk kosong! Jadi jelas satu konten bisa muat di yang lain, karena tidak ada konten di tempat pertama.

Seseorang bertanya kepada Anda, "Apakah jalan masuk Anda berisi Honda Civic?"

Tidak.

Anda berpikir bahwa isoperator menjawab pertanyaan kedua: dengan nilai ini, apakah itu cocok dengan variabel jenis itu? Apakah referensi nol cocok dengan variabel jenis ini? Ya, itu benar.

Itu bukanlah pertanyaan yang dijawab oleh isoperator. Pertanyaan yang isdijawab operator adalah pertanyaan ketiga. y is Xtidak meminta " adalah ynilai hukum dari variabel jenis X? " ia meminta " Apakah yreferensi yang valid untuk objek tipe X? " Sejak referensi nol bukan referensi yang valid untuk setiap objek setiap jenis, jawabannya adalah "tidak ada ". Jalan masuk itu kosong; itu tidak mengandung Honda Civic.

Cara lain untuk melihatnya adalah y is Xmenjawab pertanyaan "jika saya berkata y as X, apakah saya akan mendapatkan hasil bukan-nol? Jika y adalah nol, jelas jawabannya tidak!


Untuk melihat lebih dalam pada pertanyaan Anda:

Seseorang mengharapkan bahwa nilai null milik jenis referensi (atau nullable) apa pun

Seseorang akan secara implisit mengasumsikan bahwa suatu tipe adalah himpunan nilai , dan kompatibilitas penugasan dari nilai y dengan variabel tipe X tidak lebih dan tidak kurang dari memeriksa apakah y adalah anggota dari himpunan x .

Meskipun itu adalah cara yang sangat umum untuk melihat tipe, itu bukan satu - satunya cara untuk melihat tipe, dan itu bukan cara C # melihat tipe. Referensi kosong adalah anggota tanpa tipe di C #; kompatibilitas tugas ini tidak hanya memeriksa satu set untuk melihat apakah mengandung nilai. Hanya karena referensi null adalah tugas yang kompatibel dengan variabel referensi tipe X tidak berarti bahwa null adalah anggota tipe X. Relasi "adalah tugas yang kompatibel dengan" relasi dan "adalah anggota tipe" jelas memiliki banyak tumpang tindih, tetapi tidak identik di CLR.

Jika renungan tentang teori tipe menarik minat Anda, lihat artikel terbaru saya tentang masalah ini:

Apa yang Anda sebut "tipe"? Bagian satu

Apa yang Anda sebut "tipe"? Bagian kedua


@ Gebb: Senang bisa membantu. Artikel ini mungkin juga menarik bagi Anda: blogs.msdn.com/b/ericlippert/archive/2010/09/16/…
Eric Lippert


y is Xtidak bertanya "apakah ynilai hukum dari variabel tipe X?" Ini menanyakan "Apakah yreferensi yang valid untuk objek tipe X?" Itulah intinya! Terima kasih!
Jalal

Tetapi jika saya bertanya y is int?, maka saya akan bertanya "Apakah jalan masuk Anda berisi Honda Civic atau tidak sama sekali?". Mengapa jawabannya tetap tidak saat jalan masuk Anda kosong? Jika Anda melihat ke bawah kap, itu hanya akan menjadi lebih buruk, karena pertanyaannya menjadi "Apakah jalan masuk Anda berisi Honda Civic atau tanda yang bertuliskan 'Tidak Ada Honda Civic di sini'?". Meskipun jalan masuk Anda berisi tanda tersebut, jawabannya tetap tidak.
Fax

1
@ Gerard: Ketika saya memberikan jawaban yang panjang, bertele-tele, dan cerewet, orang-orang memberi tahu saya bahwa itu harus lebih pendek, dan ketika saya memberikan jawaban yang ringkas dan singkat, orang-orang memberi tahu saya bahwa itu harus lebih panjang. Kesimpulan saya adalah: orang suka mengeluh. Karena Anda memiliki perasaan tentang apa yang membuat jawaban yang baik untuk pertanyaan berusia delapan tahun ini, saran saya adalah Anda menunjukkan kepada kami apa yang membuat jawaban yang baik dengan menjawabnya sendiri, sehingga kita dapat belajar.
Eric Lippert

24

Saya pikir null is stringmengembalikan false sangat intuitif. Null tidak berarti apa-apa, dan jelas bukan string. Jadi itu harus mengembalikan false. Meskipun ini adalah pilihan yang dibuat oleh desainer bahasa, ini adalah pilihan yang sangat intuitif ketika Anda mempertimbangkan arti nol di dunia nyata.


2
1 karena pertanyaannya benar-benar tentang apakah itu intuitif dan tidak mempertanyakan spesifikasi, yang sudah diketahui oleh OP. Jika Anda menanyakannya sebagai kalimat bahasa Inggris "is nulla string" jawabannya adalah tidak, bukan, yang berbeda dari "is nullassignable to string"
Davy8

null is stringcukup intuitif, (string)null is stringmungkin memerlukan jeda jika Anda tidak terlalu familiar dengan cara kerja referensi null di C #.
decPL

24

The nullliteral dapat ditugaskan untuk setiap tipe referensi. Ini bukan tipe itu sendiri. Ini adalah literal khusus yang mewakili referensi nol.

Dalam kasus yang isakan kembali trueketika a nullakan diteruskan, apa yang dapat Anda lakukan dengan nullliteral? Tidak ada - itu null. Apa gunanya kembali truekecuali untuk hal-hal yang membingungkan?


Terlepas dari itu - dalam hal seberapa intuitifnya, baca kode dalam bahasa Inggris dan beri tahu saya:

null is string;

Ketika saya melihat itu, sepertinya saya mengajukan pertanyaan is "nothing" a string?. Intuisi saya memberi tahu saya bahwa tidak, tidak - itu nothing.


Tidak apa-apa, tapi itu juga sebuah string, bukan? Tapi mengapa (null is string)flase kembali?
Gebb

Saya akan mengatakannya sebaliknya. Jenis referensi apa pun bisa nol. null hanyalah null.
Tandai H

@ Ditambah jadi apakah nilai null adalah nilai yang valid, katakanlah, tipe objek? Saya bisa menugaskannya ke variabel jenis ini, bukan? Jadi jawabannya tampaknya ya, nilainya benar-benar valid, dan tebakan saya adalah bahwa (null is object)ekspresi tersebut harus memeriksa dengan tepat.
Gebb

@Gebb: Jangan lupa bahwa ValueTypes juga merupakan objek, tetapi bukan tipe referensi.
Markus H

1
@Oded: "Apa gunanya kembali benar kecuali untuk hal-hal yang membingungkan?" Sebenarnya, itu akan membuat bahasanya lebih logis. Pertimbangkan dua poin berikut: (1) isoperator memeriksa apakah referensi (kami tidak memerlukan jenis konversi lain di sini) konversi ada; (2) nulldapat dikonversi ke jenis referensi apa pun. Oleh karena itu (null is T), di mana T adalah tipe referensi harus mengembalikan nilai true. Tapi tidak, di sini kami memiliki pengecualian eksplisit, yang menurut saya membingungkan.
Gebb

12

http://msdn.microsoft.com/en-us/library/scekt9xw%28v=vs.71%29.aspx

Ekspresi is bernilai true jika kedua kondisi berikut terpenuhi:

  • ekspresi tidak nol.
  • ekspresi dapat dilemparkan untuk diketik. Artinya, ekspresi cast dari bentuk (jenis (ekspresi) akan selesai tanpa mengeluarkan pengecualian. Untuk informasi lebih lanjut, lihat 7.6.6 Ekspresi cast.

1
Bagaimanapun, dokumentasi hanya menyatakan bahwa ekspresi tidak boleh nol (yang sudah kita ketahui), tetapi tidak menjelaskan mengapa
nama pengguna

Mengapa Anda menginginkannya dengan cara lain?
Variabel Miserable

1
@namapengguna: Jawaban ini menjelaskan cara kerjanya secara mekanis, dan mengutip referensi, yang memberi Anda model untuk dikerjakan. Anda menanyakan arti alam semesta di sini. Saya kira Anda beruntung karena dewa kami sering mengunjungi SO;)
Merlyn Morgan-Graham

10

Praktisnya, memiliki "null is T == false" membuat saya tidak perlu mengetik kode tambahan:

Daripada harus mengatakannya

if (X != null && X is Foo) {}

Saya hanya bisa mengatakan

if (X is Foo) {}

dan selesai dengannya.


8

yang nullnilai

Saya telah mengutip ini dari pertanyaan Anda karena tampaknya hal itu menyentuh inti permasalahan. null bukanlah nilai - ini adalah ketiadaan nilai. Tujuan issaya sepertinya untuk menjawab pertanyaan:

Jika saya melakukan cast Eke T, apakah saya akan berhasil mendapatkan T?

Sekarang, meskipun Anda dapat mentransmisikan nullke T tanpa kesalahan , setelah melakukannya Anda tidak "memiliki T" - Anda masih tidak punya apa-apa. Jadi bukan kasus yang null"adalah" a T, jadi ismengembalikan salah.


3

Di Jawa ada operator yang melakukan hal yang persis sama, tetapi memiliki nama lebih lama lagi: instanceof. Sangat intuitif di sana yang null instanceof Stringmengembalikan false, karena null bukanlah instance dari apa pun, apalagi a String. Jadi, saat menggunakan nullversi Java sedikit lebih intuitif.

Namun, kedua operator tersebut mengembalikan nilai true saat diminta untuk melihat seluruh hierarki juga. Misalnya. jika contoh Stringadalah Object. Dan di sini itu Java yang ini sedikit kurang intuitif (karena contoh sebenarnya memiliki satu, jenis yang sangat spesifik) dan C # 's islebih intuitif (karena setiap String adalah sebuah Objectdalamnya dalam).

Intinya: jika Anda mencoba menggambarkan logika yang cukup canggih dalam satu kata, Anda pasti akan membuat sedikit orang bingung, dengan cara ini atau yang lain. Tampaknya sebagian besar orang setuju pada satu makna dan mereka yang tidak setuju, harus menyesuaikan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.