Spec (§7.14) mengatakan bahwa untuk ekspresi kondisional b ? x : y, ada tiga kemungkinan, baik xdan ykeduanya memiliki tipe dan kondisi baik tertentu terpenuhi, hanya satu dari xdan ymemiliki tipe dan kondisi baik tertentu terpenuhi, atau kesalahan waktu kompilasi. terjadi. Di sini, "kondisi baik tertentu" berarti konversi tertentu dimungkinkan, yang akan kita bahas di bawah ini.
Sekarang, mari kita beralih ke bagian erat dari spec:
Jika hanya satu xdan ymemiliki jenis, dan keduanya xdan ysecara implisit dapat dikonversi ke jenis itu, maka itu adalah jenis ekspresi kondisional.
Masalahnya di sini adalah bahwa di
int? number =true?5:null;
hanya satu dari hasil bersyarat yang memiliki tipe. Berikut xadalah intliteral, dan yini nullyang tidak tidak memiliki tipe dan nulltidak implisit dikonversi ke int1 . Oleh karena itu, "kondisi baik tertentu" tidak terpenuhi, dan kesalahan waktu kompilasi terjadi.
Ada yang dua cara untuk melakukannya:
int? number =true?(int?)5:null;
Di sini kita masih dalam kasus di mana hanya satu xdan ymemiliki tipe. Perhatikan bahwa nullmasih belum memiliki tipe namun kompiler tidak akan memiliki masalah dengan ini karena (int?)5dan nullkeduanya secara implisit dapat dikonversi ke int?(§6.1.4 dan §6.1.5).
Cara lainnya jelas:
int? number =true?5:(int?)null;
tetapi sekarang kita harus membaca klausa yang berbeda dalam spesifikasi untuk memahami mengapa ini tidak apa-apa:
Jika xbertipe Xdan ybertipe Ymaka
Jika konversi implisit (§6.1) ada dari Xke Y, tetapi bukan dari Yke X, maka Yadalah jenis ekspresi kondisional.
Jika konversi implisit (§6.1) ada dari Yke X, tetapi bukan dari Xke Y, maka Xadalah jenis ekspresi kondisional.
Jika tidak, tidak ada tipe ekspresi yang dapat ditentukan, dan kesalahan waktu kompilasi terjadi.
Ini xadalah tipe intdan ytipe int?. Tidak ada konversi implisit dari int?ke int, tetapi ada konversi implisit dari intke int?jadi jenis ungkapannya int?.
1 : Catat lebih jauh bahwa tipe sisi kiri diabaikan dalam menentukan tipe ekspresi bersyarat, sumber kebingungan yang umum di sini.
Mengutip spec yang baik untuk menggambarkan mengapa hal ini terjadi - +1!
JerKimball
7
Opsi lain ada new int?()di tempat (int?)null.
Guvante
1
Ini juga merupakan kasus jika Anda memiliki tipe bidang basis data yang dapat dibatalkan, misalnya DateTime yang dapat dibatalkan dan Anda mencoba dan melemparkan data ke DateTime, ketika itu diperlukan(DateTime?)
Mike Upjohn
73
null tidak memiliki tipe yang dapat diidentifikasi - hanya perlu sedikit dorongan untuk membuatnya senang:
Masalahnya bukan yang nulltidak memiliki tipe yang dapat diidentifikasi. Masalahnya adalah tidak ada konversi tersirat dari nullke int. Detail di sini .
jason
yang menarik adalah itu int? number = true ? 5 : (int?)null;dan int? number = true ? (int?)5 : null;kompilasi keduanya !! Gores, gores
davidhq
2
Aku menutupi persis mengapa hal ini terjadi di saya jawabannya .
jason
4
Seperti yang disebutkan orang lain, angka 5 adalah int, dan nulltidak dapat dikonversi secara implisit int.
Berikut adalah cara lain untuk mengatasi masalah ini:
int? num =true?5:default(int?);int? num =true?5:newint?();int? num =true?5:nullasint?;int? num =true?5:(int?)null;int? num =true?(int?)5:null;int? num =true?5asint?:null;int? num =true?newint?(5):null;
Juga, di mana pun Anda melihat int?, Anda juga bisa menggunakan Nullable<int>.
Terkadang bersyarat ?? dan?: ekspresi tidak memiliki tipe bersama yang jelas antara cabang. Kasus seperti ini gagal hari ini, tetapi C # 9.0 akan memungkinkan mereka jika ada tipe target yang dikonversi oleh kedua cabang:
Person person = student ?? customer;// Shared base typeint? result = b ?0:null;// nullable value type
Jawaban:
Spec (§7.14) mengatakan bahwa untuk ekspresi kondisional
b ? x : y
, ada tiga kemungkinan, baikx
dany
keduanya memiliki tipe dan kondisi baik tertentu terpenuhi, hanya satu darix
dany
memiliki tipe dan kondisi baik tertentu terpenuhi, atau kesalahan waktu kompilasi. terjadi. Di sini, "kondisi baik tertentu" berarti konversi tertentu dimungkinkan, yang akan kita bahas di bawah ini.Sekarang, mari kita beralih ke bagian erat dari spec:
Masalahnya di sini adalah bahwa di
hanya satu dari hasil bersyarat yang memiliki tipe. Berikut
x
adalahint
literal, dany
ininull
yang tidak tidak memiliki tipe dannull
tidak implisit dikonversi keint
1 . Oleh karena itu, "kondisi baik tertentu" tidak terpenuhi, dan kesalahan waktu kompilasi terjadi.Ada yang dua cara untuk melakukannya:
Di sini kita masih dalam kasus di mana hanya satu
x
dany
memiliki tipe. Perhatikan bahwanull
masih belum memiliki tipe namun kompiler tidak akan memiliki masalah dengan ini karena(int?)5
dannull
keduanya secara implisit dapat dikonversi keint?
(§6.1.4 dan §6.1.5).Cara lainnya jelas:
tetapi sekarang kita harus membaca klausa yang berbeda dalam spesifikasi untuk memahami mengapa ini tidak apa-apa:
Ini
x
adalah tipeint
dany
tipeint?
. Tidak ada konversi implisit dariint?
keint
, tetapi ada konversi implisit dariint
keint?
jadi jenis ungkapannyaint?
.1 : Catat lebih jauh bahwa tipe sisi kiri diabaikan dalam menentukan tipe ekspresi bersyarat, sumber kebingungan yang umum di sini.
sumber
new int?()
di tempat(int?)null
.DateTime
, ketika itu diperlukan(DateTime?)
null
tidak memiliki tipe yang dapat diidentifikasi - hanya perlu sedikit dorongan untuk membuatnya senang:sumber
int? number = true ? 5 : null as int?;
null
tidak memiliki tipe yang dapat diidentifikasi. Masalahnya adalah tidak ada konversi tersirat darinull
keint
. Detail di sini .int? number = true ? 5 : (int?)null;
danint? number = true ? (int?)5 : null;
kompilasi keduanya !! Gores, goresSeperti yang disebutkan orang lain, angka 5 adalah
int
, dannull
tidak dapat dikonversi secara implisitint
.Berikut adalah cara lain untuk mengatasi masalah ini:
Juga, di mana pun Anda melihat
int?
, Anda juga bisa menggunakanNullable<int>
.sumber
Dalam
C# 9
hal ini sekarang diperbolehkan blogAtau contoh Anda:
sumber