Di C # 7 kita bisa menggunakan
if (x is null) return;
dari pada
if (x == null) return;
Apakah ada keuntungan menggunakan cara baru (contoh sebelumnya) dibandingkan cara lama?
Apakah semantiknya berbeda?
Apakah hanya masalah selera? Jika tidak, kapan saya harus menggunakan yang satu?
Referensi: Apa yang Baru di C # 7.0 .
Jawaban:
Pembaruan: Kompilator Roslyn telah diperbarui untuk membuat perilaku kedua operator sama ketika tidak ada operator kesetaraan yang kelebihan beban . Silakan lihat kode dalam hasil kompiler saat ini (
M1
danM2
dalam kode) yang menunjukkan apa yang terjadi ketika tidak ada pembanding kesetaraan kelebihan beban. Mereka berdua sekarang memiliki==
perilaku yang lebih baik . Jika ada pembanding kesetaraan kelebihan beban, kode masih berbeda .Lihat untuk versi yang lebih lama dari kompiler Roslyn analisis di bawah ini.
Karena
null
tidak ada perbedaan dengan apa yang biasa kita gunakan dengan C # 6. Namun, hal-hal menjadi menarik ketika Anda berubahnull
ke konstanta lain.Ambil ini sebagai contoh:
Tes menghasilkan
a
. Jika Anda membandingkannya dengano == (object)1
apa yang Anda tulis secara normal, itu membuat perbedaan besar.is
mempertimbangkan jenis di sisi lain perbandingan. Itu keren!Saya pikir pola
== null
vsis null
konstan adalah sesuatu yang sangat akrab dengan 'kebetulan', di mana sintaksisis
operator dan operator sederajat menghasilkan hasil yang sama.Seperti svick berkomentar,
is null
panggilanSystem.Object::Equals(object, object)
tempat==
panggilanceq
.IL untuk
is
:IL untuk
==
:Karena kita berbicara tentang
null
, tidak ada perbedaan karena ini hanya membuat perbedaan pada instance . Ini bisa berubah ketika Anda telah kelebihan beban operator kesetaraan.sumber
is
panggilanobject.Equals(x, null)
, sementara==
dikompilasi sebagaiceq
. Tetapi hasilnya harus sama, seperti yang Anda katakan.==
adalah operator yang kelebihan beban. Anda dapat memiliki perilaku yang Anda inginkan dengannya. Untuk misalnya ini diterapkan aneh==
tidak akan memberi tahu Anda jika instance Anda benar-benar nol.is null
di sisi lain akan selalu mengembalikan true untuk referensi nol sejati :) Juga, jika Anda memilikiReferenceEquals
dalam kode Anda, bola lampu VS 2017 akan menyarankan untuk berubah menjadiis null
, bukan== null
(dengan benar).is
tidak lagi memiliki overhead panggilan fungsi ketika digunakan untuk memeriksa null. Sebagai buktinya, lihat tautan yang diposting oleh @svick di komentar.Kelebihan muatan sama dengan operator
Sebenarnya ada perbedaan dalam semantik antara dua perbandingan ketika Anda membandingkan
null
dengan jenis yang telah membebani==
operator.foo is null
akan menggunakan perbandingan referensi langsung untuk menentukan hasilnya, sedangkanfoo == null
tentu saja akan menjalankan==
operator yang kelebihan beban jika ada.Dalam contoh ini saya telah memperkenalkan "bug" pada
==
operator yang kelebihan beban , menyebabkannya selalu mengeluarkan pengecualian jika argumen kedua adalahnull
:Kode IL untuk
foo is null
menggunakanceq
instruksi untuk melakukan perbandingan referensi langsung:Kode IL untuk
foo == null
menggunakan panggilan ke operator yang kelebihan beban:Jadi perbedaannya adalah, bahwa jika Anda menggunakan
==
Anda berisiko menjalankan kode pengguna (yang berpotensi memiliki perilaku yang tidak terduga atau masalah kinerja).Pembatasan obat generik
Menggunakan
is null
konstruk membatasi tipe ke tipe referensi. Kompiler memastikan hal ini, yang berarti Anda tidak dapat menggunakanis null
tipe nilai. Jika Anda memiliki metode generik, Anda tidak akan dapat menggunakanis null
kecuali tipe generik dibatasi menjadi tipe referensi.Terima kasih kepada David Augusto Villa yang telah menunjukkan ini.
sumber