Pertanyaan Mengapa ?: menyebabkan kesalahan konversi sementara jika tidak? [duplikat]


Pertanyaan ini sudah memiliki jawaban di sini:

Membuat beberapa perubahan dalam kode yang saya gunakan baris berikutnya:

uint a = b == c ? 0 : 1;

Visual Studio menunjukkan kepada saya kesalahan ini:

Tidak dapat secara implisit mengubah tipe 'int' menjadi 'uint'. Konversi eksplisit ada (apakah Anda kehilangan gips?)

Tetapi jika saya menggunakan kode:

uint a; 

if (b == c) 
    a = 0; 
else 
    a = 1;

Ia bekerja dengan benar tanpa kesalahan atau peringatan. Mengapa?


75
2018-03-09 08:18


asal


Jawaban:


Mengapa saya tidak bisa menggunakannya uint a = b == c ? 0 : 1;?

Jenis ekspresi b == c ? 0 : 1 aku s int. Seperti yang ditunjukkan di meja ini, tidak ada konversi implisit dari int untuk uint, jadi ini tidak diizinkan.

Mengapa saya bisa menggunakannya a = 0?

Karena ada perlakuan khusus dari tipe numerik ketika nilainya adalah ekspresi konstan.

Dari bagian 6.1.9 dari spesifikasi C #:

  • Ekspresi tipe int yang konstan dapat dikonversi menjadi tipe sbyte, byte, short, ushort, uint, atau ulong, asalkan nilai dari ekspresi-konstan berada dalam jangkauan tipe tujuan.

  • Ekspresi tipe panjang konstan dapat dikonversi ke tipe ulong, asalkan nilai dari ekspresi konstan tidak negatif.

Seperti yang ditunjukkan dalam peluru pertama a = 0 dan a = 1 keduanya diizinkan karena 0 dan 1 adalah ekspresi konstan dan valid uint nilai-nilai. Pada dasarnya apa ini intinya adalah bahwa compiler dapat dengan mudah menentukan pada waktu kompilasi bahwa konversi ini valid, sehingga memungkinkan mereka.

Kebetulan, jika b == c bagian dari contoh pertama Anda diubah menjadi ekspresi konstan (mis. true), maka seluruh ekspresi operator kondisional akan menjadi ekspresi konstan dan kode akan dikompilasi.


87
2018-03-09 08:27



Jika  b==c adalah ekspresi konstan maka seluruh operator kondisional akan dianggap sebagai ekspresi konstan dan karenanya, kemudian, aturan yang memungkinkan ekspresi tipe konstan int untuk dikonversi ke int lainnya akan berlaku dan akan dikompilasi.

Tentunya, b==c bukan ekspresi konstan sehingga hasil dari operator kondisional tidak dapat diketahui hingga runtime sehingga pengecualian yang memungkinkan konversi implisit ints ke uint (untuk ekspresi konstan) tidak berlaku.

Di dalam Anda if/else varian, kedua dari penugasan yang sebenarnya adalah ekspresi konstan.


26
2018-03-09 08:28



Kamu harus menggunakan literal untuk membuat kode berfungsi dengan benar seperti ini:

uint a = b == c ? 0U : 1U;

10
2018-03-09 08:22