Saya perhatikan bahwa Resharper menyarankan agar saya mengubah ini:
if (myObj.myProp is MyType)
{
...
}
ke dalam ini:
var myObjRef = myObj.myProp as MyType;
if (myObjRef != null)
{
...
}
Mengapa ini menyarankan perubahan ini? Saya terbiasa dengan Resharper yang menyarankan perubahan pengoptimalan dan perubahan pengurangan kode, tetapi ini terasa seperti ingin mengambil pernyataan tunggal saya dan mengubahnya menjadi dua baris.
Menurut MSDN :
Sebuah adalah ekspresi mengevaluasi true jika kedua kondisi berikut terpenuhi:
ekspresi tidak nol. ekspresi dapat dilemparkan untuk diketik . Artinya, ekspresi cast formulir
(type)(expression)
akan selesai tanpa mengeluarkan pengecualian.
Apakah saya salah membaca itu, atau tidak is
melakukan pemeriksaan yang sama persis, hanya dalam satu baris tanpa perlu secara eksplisit membuat variabel lokal lain untuk pemeriksaan null?
MyProp
pengambil setelah perubahan ini.Jawaban:
Karena hanya ada satu pemeran. Bandingkan ini:
untuk ini:
C # 7.0 mendukung sintaks yang lebih ringkas menggunakan pencocokan pola :
sumber
as
mungkin beberapa nanodetik lebih cepat, tapi saya menganggap ini sebagai pengoptimalan mikro prematur.myObj
ataumyProp
bisa berubah (oleh utas lain) antarais
dan pemeran, menyebabkan perilaku yang tidak diinginkan.as
+!= null
juga akan mengeksekusi!=
operator yang digantiMyType
jika ditentukan (bahkan jikamyObjRef
nol). Meskipun dalam banyak kasus ini bukan masalah (terutama jika Anda menerapkannya dengan benar), dalam beberapa kasus ekstrim (kode buruk, kinerja) mungkin tidak diinginkan. ( meskipun harus sangat ekstrim )object.ReferenceEquals(null, myObjRef)
.Pilihan terbaik adalah menggunakan pencocokan pola seperti itu:
sumber
Belum ada informasi tentang apa yang sebenarnya terjadi di bawah ikat pinggang. Lihat contoh ini:
Ini diterjemahkan menjadi IL berikut:
Yang penting di sini adalah panggilan
isinst
dancastclass
- keduanya relatif mahal. Jika Anda membandingkannya dengan alternatif, Anda hanya dapat melihatnya melakukanisinst
pemeriksaan:Juga perlu disebutkan adalah bahwa tipe nilai akan digunakan
unbox.any
daripadacastclass
:Namun perlu dicatat bahwa ini tidak selalu berarti hasil yang lebih cepat seperti yang kita lihat di sini . Ada tampaknya telah perbaikan sejak pertanyaan yang diminta meskipun: gips tampaknya dilakukan secepat mereka dulu tapi
as
danlinq
sekarang sekitar 3 kali lebih cepat.sumber
Peringatan Resharper:
"Type check and direct cast can be replaced with try cast and check for null"
Keduanya akan berfungsi, itu tergantung bagaimana kode Anda lebih cocok untuk Anda. Dalam kasus saya, saya mengabaikan peringatan itu:
Dalam kode saya cara ke-2 lebih lama dan kinerja yang lebih buruk.
sumber
IRunable
. Jika Anda tidak memiliki kendali, mungkin Anda bisa menggunakandynamic
?Bagi saya ini tampaknya tergantung pada kemungkinan besar itu akan menjadi jenis itu atau tidak. Ini tentu akan lebih efisien untuk melakukan pengecoran di depan jika objek tersebut sebagian besar waktu. Jika hanya sesekali dari jenis itu maka mungkin lebih optimal untuk diperiksa dulu dengan is.
Biaya pembuatan variabel lokal sangat kecil dibandingkan dengan biaya pemeriksaan tipe.
Keterbacaan dan cakupan adalah faktor yang lebih penting bagi saya biasanya. Saya tidak setuju dengan ReSharper, dan menggunakan operator "adalah" untuk alasan itu saja; optimalkan nanti jika ini benar-benar hambatan.
(Saya berasumsi bahwa Anda hanya menggunakan
myObj.myProp is MyType
sekali dalam fungsi ini)sumber
Ini harus menyarankan perubahan kedua juga:
ke
Ini menghemat akses properti dan pemeran, dibandingkan dengan kode asli. Tapi itu hanya mungkin setelah berubah
is
menjadias
.sumber
(MyType)
akan memunculkan pengecualian jika cast gagal.as
hanya kembalinull
.is
(kode itu ada dalam pertanyaan).Saya akan mengatakan ini untuk membuat versi myObj.myProp yang sangat diketik, yaitu myObjRef. Ini kemudian harus digunakan saat Anda mereferensikan nilai ini di blok, vs. harus melakukan cast.
Misalnya, ini:
lebih baik dari ini:
sumber