Apakah ada perbedaan antara dua bagian kode berikut?
class Test {
public readonly double Val;
public Test(bool src) {
this.Val = src ? 1 : 0;
}
}
class Test {
public readonly double Val;
public Test(bool src) {
this.Val = src ? 1D : 0D;
}
}
Saya menemukan bahwa basis kode kami menggunakan cara penulisan yang kedua.
Jawaban:
Ada dua pertanyaan di sini dan penting untuk dicatat bahwa mereka memiliki jawaban yang berbeda.
Tidak. Kompiler C # mengenali kapan integer literal digunakan dalam konteks di mana double diharapkan dan apakah tipe berubah pada waktu kompilasi, sehingga dua fragmen ini akan menghasilkan kode yang sama.
Iya. Aturan bahwa konstanta integer secara otomatis diubah menjadi ganda hanya berlaku untuk konstanta , dan
src ? ...
bukan konstanta . Kompiler akan menghasilkan yang pertama seolah-olah Anda menulis:Dan yang kedua sebagai
Yaitu, di pertama kita memilih integer dan kemudian mengubahnya menjadi dua kali lipat, dan di kedua kita memilih ganda.
FYI: kompiler C # atau jitter diizinkan untuk mengenali bahwa program pertama dapat dioptimalkan menjadi yang kedua, tapi saya tidak tahu apakah itu benar-benar melakukannya. Kompiler C # kadang - kadang memindahkan konversi untuk aritmatika terangkat ke tubuh kondisional; Saya menulis kode itu sekitar delapan tahun yang lalu sekarang, tetapi saya tidak ingat semua detailnya.
sumber
Ada adalah perbedaan dalam kode IL yang dihasilkan.
Kelas ini:
Menghasilkan kode IL ini untuk konstruktor:
Dan kelas ini:
Menghasilkan kode IL ini untuk konstruktor:
Seperti yang Anda lihat, dalam versi pertama ia harus memanggil
conv.r8
untuk mengkonversi int menjadi ganda.Namun: (1) Hasil akhirnya identik dan (2) kompiler JIT dapat menerjemahkan keduanya ke kode mesin yang sama.
Jadi jawabannya adalah: Ya, ada adalah perbedaan - tapi tidak satu yang Anda perlu khawatir tentang.
Secara pribadi, saya akan menggunakan versi kedua karena itu lebih baik mengekspresikan maksud programmer, dan dapat menghasilkan kode yang sangat sangat sedikit lebih efisien (tergantung pada apa yang dilakukan kompiler JIT).
sumber
Tidak ada perbedaan, kompiler cukup pintar untuk secara implisit melakukan konversi atau tidak.
Namun, jika Anda gunakan
var
, Anda perlu menulisvar val = 42D;
untuk memastikan variabelnya ganda dan bukan int.sumber