Evaluasi hubungan pendek, apakah itu praktik buruk?

88

Sesuatu yang saya kenal untuk sementara waktu tetapi tidak pernah dipertimbangkan adalah bahwa dalam sebagian besar bahasa adalah mungkin untuk memberikan prioritas kepada operator dalam pernyataan if berdasarkan pesanan mereka. Saya sering menggunakan ini sebagai cara untuk mencegah pengecualian referensi nol, misalnya:

if (smartphone != null && smartphone.GetSignal() > 50)
{
   // Do stuff
}

Dalam hal ini kode akan menghasilkan pengecekan pertama bahwa objek tersebut tidak nol dan kemudian menggunakan objek ini mengetahui bahwa itu ada. Bahasa ini pintar karena ia tahu bahwa jika pernyataan pertama jika salah maka tidak ada gunanya mengevaluasi pernyataan kedua sehingga pengecualian referensi nol tidak pernah dilempar. Ini bekerja sama untuk anddan oroperator.

Ini dapat berguna dalam situasi lain juga seperti memeriksa bahwa indeks berada dalam batas-batas array dan teknik seperti itu dapat dilakukan dalam berbagai bahasa, setahu saya: Java, C #, C ++, Python dan Matlab.

Pertanyaan saya adalah: Apakah kode semacam ini merupakan representasi praktik buruk? Apakah praktik buruk ini muncul dari beberapa masalah teknis tersembunyi (yaitu hal ini pada akhirnya dapat menyebabkan kesalahan) atau apakah hal itu menyebabkan masalah keterbacaan untuk programmer lain? Mungkinkah ini membingungkan?

Innova
sumber
69
Istilah teknisnya adalah evaluasi hubung singkat . Ini adalah teknik implementasi yang terkenal, dan di mana standar bahasa menjaminnya, mengandalkannya adalah hal yang baik. (Jika tidak, ini bukan bahasa, IMO.)
Kilian Foth
3
Sebagian besar bahasa memungkinkan Anda memilih perilaku apa yang Anda inginkan. Dalam C # ||hubung singkat operator , operator |(pipa tunggal) tidak ( &&dan &berperilaku sama). Karena operator hubung singkat lebih sering digunakan, saya sarankan untuk menandai penggunaan yang bukan hubung singkat dengan komentar untuk menjelaskan mengapa Anda memerlukan perilaku mereka (kebanyakan hal seperti pemanggilan metode yang semuanya harus terjadi).
linac
14
@linac sekarang meletakkan sesuatu di sisi kanan &atau |untuk memastikan efek samping terjadi adalah sesuatu yang saya katakan tentu saja adalah praktik yang buruk: Tidak akan dikenakan biaya apa pun untuk melakukan panggilan metode pada jalurnya sendiri.
Jon Hanna
14
@ Linac: Dalam C dan C ++, &&adalah hubungan arus pendek dan &tidak, tapi mereka operator yang sangat berbeda. &&adalah logis "dan"; &adalah bitwise "and". Adalah mungkin untuk x && ymenjadi benar sementara x & yitu salah.
Keith Thompson
3
Contoh spesifik Anda dapat praktik buruk karena alasan lain: bagaimana jika itu adalah nol? Apakah masuk akal untuk membatalkannya di sini? Kenapa itu nol? Haruskah seluruh fungsi di luar blok ini dieksekusi jika itu nol, apakah semuanya tidak melakukan apa-apa, atau haruskah program Anda berhenti? Menempelkan "jika nol" pada setiap akses (mungkin karena pengecualian referensi nol Anda terburu-buru untuk menyingkirkan) berarti bahwa Anda bisa masuk agak jauh ke dalam sisa program, tanpa pernah memperhatikan bahwa inisialisasi objek telepon kacau. naik. Dan akhirnya, ketika Anda akhirnya mendapatkan sedikit kode yang tidak tidak
Random832

Jawaban:

125

Tidak, ini bukan praktik buruk. Mengandalkan hubungan arus pendek kondisi adalah teknik bermanfaat yang diterima secara luas - selama Anda menggunakan bahasa yang menjamin perilaku ini (yang mencakup sebagian besar bahasa modern).

Contoh kode Anda cukup jelas dan, memang, itu sering kali merupakan cara terbaik untuk menulisnya. Alternatif (seperti ifpernyataan bersarang ) akan menjadi berantakan, lebih rumit, dan karenanya lebih sulit untuk dipahami.

Beberapa peringatan:

Gunakan akal sehat tentang kompleksitas dan keterbacaan

Berikut ini bukan ide yang bagus:

if ((text_string != null && replace(text_string,"$")) || (text_string = get_new_string()) != null)

Seperti banyak cara "pintar" untuk mengurangi garis-garis dalam kode Anda, terlalu mengandalkan teknik ini dapat menghasilkan kode yang mudah dipahami dan rentan kesalahan.

Jika Anda perlu menangani kesalahan, seringkali ada cara yang lebih baik

Contoh Anda baik-baik saja asalkan kondisi program normal untuk ponsel cerdas adalah nol. Namun, jika ini adalah kesalahan, Anda harus memasukkan penanganan kesalahan yang lebih cerdas.

Hindari pemeriksaan berulang dengan kondisi yang sama

Seperti yang ditunjukkan Neil, banyak pemeriksaan berulang dari variabel yang sama dalam kondisi yang berbeda kemungkinan besar merupakan bukti cacat desain. Jika Anda memiliki sepuluh pernyataan yang berbeda ditaburi melalui kode Anda yang tidak boleh dijalankan jika smartphoneini null, mempertimbangkan apakah ada cara yang lebih baik untuk menangani ini selain memeriksa variabel setiap kali.

Ini bukan tentang hubungan arus pendek secara khusus; itu masalah yang lebih umum dari kode berulang. Namun, perlu disebutkan, karena cukup umum untuk melihat kode yang memiliki banyak pernyataan berulang seperti pernyataan contoh Anda.

Deduplicator
sumber
12
Perlu dicatat bahwa diulangi jika blok memeriksa jika instance nol dalam evaluasi hubung singkat mungkin harus ditulis ulang untuk melakukan pemeriksaan itu hanya sekali.
Neil
1
@ Neil, poin bagus; Saya memperbarui jawabannya.
2
Satu-satunya hal yang dapat saya pikirkan untuk ditambahkan adalah mencatat cara opsional lain untuk menanganinya, yang benar-benar disukai jika Anda akan memeriksa sesuatu dalam berbagai kondisi yang berbeda: periksa untuk melihat apakah ada sesuatu yang nol dalam if (), lalu kembali / lempar - jika tidak teruskan saja. Ini menghilangkan bersarang dan sering dapat membuat kode lebih eksplisit dan singkat, seperti "ini tidak boleh nol dan jika itu maka saya keluar dari sini" - ditempatkan di awal kode sebagai bijaksana mungkin. Hebat kapan saja Anda membuat kode sesuatu yang memeriksa kondisi tertentu lebih dari satu tempat dalam suatu metode.
BrianH
1
@ dan1111 Saya akan menggeneralisasi contoh yang Anda berikan sebagai "Suatu kondisi tidak boleh mengandung efek samping (seperti penugasan variabel di atas). Evaluasi hubung singkat tidak mengubah ini dan tidak boleh digunakan sebagai short-hand untuk sisi- efek yang bisa dengan mudah ditempatkan di tubuh if untuk lebih mewakili hubungan if / then. "
AaronLS
@ AaronLS, saya sangat tidak setuju dengan klaim bahwa "suatu kondisi tidak boleh mengandung efek samping". Suatu kondisi seharusnya tidak perlu membingungkan, tetapi selama itu adalah kode yang jelas, saya baik-baik saja dengan efek samping (atau bahkan lebih dari satu efek samping) dalam suatu kondisi.
26

Katakanlah Anda menggunakan bahasa gaya-C tanpa &&dan perlu melakukan kode yang sama seperti dalam pertanyaan Anda.

Kode Anda adalah:

if(smartphone != null)
{
  if(smartphone.GetSignal() > 50)
  {
    // Do stuff
  }
}

Pola ini akan banyak muncul.

Sekarang bayangkan versi 2.0 dari bahasa hipotetis kita memperkenalkan &&. Pikirkan betapa kerennya Anda!

&&adalah cara idiomatis yang diakui untuk melakukan apa yang dilakukan oleh contoh saya di atas. Ini bukan praktik buruk untuk menggunakannya, memang itu praktik buruk untuk tidak menggunakannya dalam kasus-kasus seperti di atas: Seorang programmer yang berpengalaman dalam bahasa seperti itu akan bertanya-tanya di mana elseitu atau alasan lain untuk tidak melakukan sesuatu dengan cara normal.

Bahasa ini pintar karena ia tahu bahwa jika pernyataan pertama jika salah maka tidak ada gunanya mengevaluasi pernyataan kedua sehingga pengecualian referensi nol tidak pernah dilempar.

Tidak, Anda pintar, karena Anda tahu bahwa jika pernyataan pertama salah maka tidak ada gunanya mengevaluasi pernyataan kedua. Bahasa ini bodoh seperti sekotak batu dan melakukan apa yang Anda perintahkan. (John McCarthy bahkan lebih pintar, dan menyadari bahwa evaluasi hubung singkat akan menjadi hal yang berguna bagi bahasa untuk dimiliki).

Perbedaan antara Anda menjadi pintar dan bahasa menjadi pintar adalah penting, karena praktik yang baik dan buruk sering kali membuat Anda menjadi sepintar yang diperlukan, tetapi tidak lagi pintar.

Mempertimbangkan:

if(smartphone != null && smartphone.GetSignal() > ((range = (range != null ? range : GetRange()) != null && range.Valid ? range.MinSignal : 50)

Ini memperluas kode Anda untuk memeriksa a range. Jika rangeisinya nol maka ia mencoba menyetelnya dengan panggilan GetRange()meskipun mungkin gagal jadi rangemungkin masih nol. Jika rentang tidak nol setelah ini, dan Validkemudian MinSignalpropertinya digunakan, jika tidak maka default 50digunakan.

Ini tergantung pada &&juga, tetapi meletakkannya dalam satu baris mungkin terlalu pintar (saya tidak 100% yakin saya sudah benar, dan saya tidak akan memeriksa ulang karena fakta itu menunjukkan maksud saya).

Bukan &&itu masalahnya di sini, tetapi kemampuan untuk menggunakannya untuk menempatkan banyak dalam satu ekspresi (hal yang baik) meningkatkan kemampuan kita untuk menulis ekspresi yang sulit dipahami secara tidak perlu (hal yang buruk).

Juga:

if(smartphone != null && (smartphone.GetSignal() == 2 || smartphone.GetSignal() == 5 || smartphone.GetSignal() == 8 || smartPhone.GetSignal() == 34))
{
  // do something
}

Di sini saya menggabungkan penggunaan &&dengan memeriksa nilai-nilai tertentu. Ini tidak realistis dalam hal sinyal telepon, tetapi muncul dalam kasus lain. Di sini, ini adalah contoh saya tidak cukup pintar. Jika saya melakukan hal berikut:

if(smartphone != null)
{
  switch (smartphone.GetSignal())
  {
    case 2: case 5: case 8: case 34:
      // Do something
      break;
  }
}

Saya akan mendapatkan baik keterbacaan dan juga kemungkinan dalam kinerja (beberapa panggilan ke GetSignal()kemungkinan tidak akan dioptimalkan).

Lagi-lagi, masalahnya bukan &&pada mengambil palu itu dan menganggap yang lainnya sebagai paku; tidak menggunakannya biarkan aku melakukan sesuatu yang lebih baik daripada menggunakannya.

Kasus terakhir yang menjauh dari praktik terbaik adalah:

if(a && b)
{
  //do something
}

Dibandingkan dengan:

if(a & b)
{
  //do something
}

Argumen klasik tentang mengapa kita mungkin mendukung yang terakhir adalah bahwa ada beberapa efek samping dalam menilai byang kita inginkan apakah abenar atau tidak. Saya tidak setuju tentang itu: Jika efek samping itu sangat penting, maka wujudkan dalam baris kode yang terpisah.

Namun, dalam hal efisiensi, keduanya kemungkinan lebih baik. Yang pertama jelas akan mengeksekusi lebih sedikit kode (tidak menilai bsama sekali dalam satu jalur kode) yang dapat menyelamatkan kita berapa pun waktu yang diperlukan untuk menilai b.

Yang pertama juga memiliki satu cabang lagi. Pertimbangkan jika kita menulis ulang dalam bahasa C-style hipotetis kita tanpa &&:

if(a)
{
  if(b)
  {
    // Do something
  }
}

Ekstra ifitu tersembunyi dalam penggunaan kita &&, tetapi masih ada. Dan karena itu adalah kasus di mana ada prediksi cabang terjadi dan karena itu berpotensi salah prediksi cabang.

Untuk alasan itu, if(a & b)kode dapat lebih efisien dalam beberapa kasus.

Di sini saya akan mengatakan bahwa if(a && b)masih merupakan pendekatan praktik terbaik untuk memulai dengan: Lebih umum, satu-satunya yang layak dalam beberapa kasus (di mana bkesalahan jika asalah) dan lebih cepat lebih cepat daripada tidak. Perlu dicatat bahwa if(a & b)sering kali optimasi yang berguna untuk itu dalam kasus tertentu.

Jon Hanna
sumber
1
Jika seseorang memiliki trymetode yang kembali truejika sukses, apa yang Anda pikirkan if (TryThis || TryThat) { success } else { failure }? Ini adalah idiom yang kurang umum, tetapi saya tidak tahu bagaimana menyelesaikan hal yang sama tanpa duplikasi kode atau menambahkan flag. Sementara memori yang diperlukan untuk sebuah bendera tidak menjadi masalah, dari sudut pandang analisis, menambahkan bendera secara efektif membagi kode menjadi dua alam semesta paralel - satu berisi pernyataan yang dapat dijangkau ketika bendera itu truedan satu pernyataan lainnya dapat dijangkau ketika itu false. Terkadang bagus dari perspektif KERING, tapi menjengkelkan.
supercat
5
Saya tidak melihat ada yang salah dengan itu if(TryThis || TryThat).
Jon Hanna
3
Sungguh jawaban yang bagus, tuan.
Uskup
FWIW, programmer yang hebat termasuk Kernighan, Plauger & Pike dari Bell Labs merekomendasikan demi kejelasan untuk menggunakan struktur kontrol dangkal seperti if {} else if {} else if {} else {}daripada struktur kontrol bersarang seperti if { if {} else {} } else {}, bahkan jika itu berarti mengevaluasi ekspresi yang sama lebih dari sekali. Linus Torvalds mengatakan sesuatu yang serupa: "jika Anda membutuhkan lebih dari 3 level indentasi, Anda tetap kacau". Mari kita anggap itu sebagai suara untuk operator hubung singkat.
Sam Watkins
jika (a && b) pernyataan; cukup mudah untuk diganti. if (a && b && c && d) statement1; pernyataan lain2; adalah rasa sakit yang nyata.
gnasher729
10

Anda dapat mengambil ini lebih jauh, dan dalam beberapa bahasa itu adalah cara idiomatis untuk melakukan sesuatu: Anda dapat menggunakan evakuasi hubung singkat di luar pernyataan bersyarat juga, dan mereka menjadi bentuk pernyataan bersyarat sendiri. Misalnya dalam Perl, itu adalah idiomatik bagi fungsi untuk mengembalikan sesuatu yang salah pada kegagalan (dan sesuatu yang benar pada kesuksesan), dan sesuatu seperti

open($handle, "<", "filename.txt") or die "Couldn't open file!";

idiom. openmengembalikan sesuatu yang bukan nol pada kesuksesan (sehingga diebagian setelah ortidak pernah terjadi), tetapi tidak didefinisikan pada kegagalan, dan kemudian panggilan untuk dieitu terjadi (itulah cara Perl untuk mengajukan pengecualian).

Itu bagus dalam bahasa di mana semua orang melakukannya.

RemcoGerlich
sumber
17
Kontribusi terbesar Perl untuk desain bahasa adalah untuk memberikan banyak contoh bagaimana tidak melakukannya.
Jack Aidley
@JackAidley: Saya rindu Perl unless, dan postfix conditional ( send_mail($address) if defined $address).
RemcoGerlich
6
@JackAidley dapatkah Anda memberikan petunjuk mengapa 'atau mati' buruk? Apakah itu hanya cara naif dalam menangani pengecualian?
bigstones
Dimungkinkan untuk melakukan banyak hal buruk di Perl, tetapi saya gagal melihat masalah dengan contoh ini. Ini sederhana, pendek, dan jelas - persis apa yang Anda inginkan dari penanganan kesalahan dalam bahasa scripting.
1
@RemcoGerlich Ruby mewarisi beberapa gaya itu:send_mail(address) if address
bonh
6

Walaupun saya umumnya setuju dengan jawaban dan1111 , ada satu kasus penting yang tidak dibahas: kasus di mana smartphonedigunakan secara bersamaan. Dalam skenario itu, pola semacam ini merupakan sumber yang sulit ditemukan bug.

Masalahnya adalah bahwa evaluasi hubung singkat tidak atomik. Utas Anda dapat memeriksa apakah smartphoneitu null, utas lain dapat masuk dan membatalkannya, lalu utas Anda segera mencoba untuk GetSignal()dan meledak.

Tapi tentu saja, itu hanya melakukan itu ketika bintang-bintang menyelaraskan dan waktu benang Anda adalah hanya benar.

Jadi, meskipun kode semacam ini sangat umum dan bermanfaat, penting untuk mengetahui peringatan ini sehingga Anda dapat secara akurat mencegah bug jahat ini.

Telastyn
sumber
3

Ada banyak situasi di mana saya ingin memeriksa satu kondisi terlebih dahulu, dan hanya ingin memeriksa kondisi kedua jika kondisi pertama berhasil. Kadang-kadang murni untuk efisiensi (karena tidak ada gunanya memeriksa kondisi kedua jika yang pertama sudah gagal), kadang-kadang karena kalau tidak program saya akan crash (cek Anda untuk NULL pertama), kadang-kadang karena kalau tidak hasilnya akan mengerikan. (JIKA (saya ingin mencetak dokumen) DAN (mencetak dokumen gagal)) KEMUDIAN menampilkan pesan kesalahan - Anda tidak ingin mencetak dokumen dan memeriksa apakah pencetakan gagal jika Anda tidak ingin mencetak dokumen di tempat pertama!

Jadi ada kebutuhan BESAR untuk evaluasi hubung singkat ekspresi logis dijamin. Itu tidak hadir di Pascal (yang memiliki evaluasi hubung singkat tidak dijamin) yang merupakan rasa sakit utama; Saya pertama kali melihatnya di Ada dan C.

Jika Anda benar-benar berpikir ini adalah "praktik buruk", maka silakan ambil sedikit kode yang cukup kompleks, tulis ulang sehingga akan berfungsi dengan baik tanpa evaluasi hubungan pendek, dan kembali dan beri tahu kami bagaimana Anda menyukainya. Ini seperti diberi tahu bahwa pernapasan menghasilkan karbon dioksida dan menanyakan apakah pernapasan adalah praktik yang buruk. Cobalah tanpanya selama beberapa menit.

gnasher729
sumber
"Tulis ulang sehingga itu akan bekerja dengan baik tanpa evaluasi hubungan pendek, dan kembali dan beri tahu kami bagaimana Anda menyukainya." - Ya, ini membawa kembali kenangan Pascal. Dan tidak, saya tidak menyukainya.
Thomas Padron-McCarthy
2

Satu pertimbangan, tidak disebutkan dalam jawaban lain: kadang-kadang memiliki pemeriksaan ini dapat mengisyaratkan kemungkinan refactoring ke pola desain Obyek Null . Sebagai contoh:

if (currentUser && currentUser.isAdministrator()) 
  doSomething();

Bisa disederhanakan menjadi:

if (currentUser.isAdministrator())
  doSomething ();

Jika currentUserdefault untuk beberapa 'pengguna anonim' atau 'pengguna nol' dengan implementasi mundur jika pengguna tidak masuk.

Tidak selalu bau kode, tetapi sesuatu yang perlu dipertimbangkan.

Pete
sumber
-4

Saya akan menjadi tidak populer dan berkata Ya, ini adalah praktik yang buruk. JIKA fungsionalitas kode Anda bergantung padanya untuk menerapkan logika kondisional.

yaitu

 if(quickLogicA && slowLogicB) {doSomething();}

itu bagus, tapi

if(logicA && doSomething()) {andAlsoDoSomethingElse();}

buruk, dan pasti tidak ada yang akan setuju?

if(doSomething() || somethingElseIfItFailed() && anotherThingIfEitherWorked() & andAlwaysThisThing())
{/* do nothing */}

Alasan:

Kesalahan kode Anda jika kedua belah pihak dievaluasi daripada hanya tidak melakukan logika. Telah diperdebatkan bahwa ini bukan masalah, operator 'dan' didefinisikan dalam c # jadi artinya jelas. Namun, saya berpendapat bahwa ini tidak benar.

Alasan 1. Historis

Pada dasarnya Anda mengandalkan (apa yang awalnya dimaksudkan) pengoptimalan kompiler untuk menyediakan fungsionalitas dalam kode Anda.

Meskipun dalam c # spesifikasi bahasa menjamin operator boolean 'dan' melakukan hubungan arus pendek. Ini tidak berlaku untuk semua bahasa dan kompiler.

wikipeda mencantumkan berbagai bahasa dan pendapat mereka tentang hubungan pendek http://en.wikipedia.org/wiki/Short-circuit_evaluation karena Anda dapat, ada banyak pendekatan. Dan beberapa masalah tambahan saya tidak pergi ke sini.

Secara khusus, FORTRAN, Pascal dan Delphi memiliki flag compiler yang mengubah perilaku ini.

Oleh karena itu: Anda mungkin menemukan kode Anda berfungsi ketika dikompilasi untuk rilis, tetapi tidak untuk debug atau dengan kompiler alternatif dll.

Alasan 2. Perbedaan bahasa

Seperti yang Anda lihat dari wikipedia, tidak semua bahasa menggunakan pendekatan yang sama untuk hubungan pendek, bahkan ketika mereka menentukan bagaimana operator boolean harus menanganinya.

Khususnya operator 'dan' VB.Net tidak mengalami hubungan pendek dan TSQL memiliki beberapa kekhasan.

Mengingat bahwa 'solusi' modern kemungkinan akan mencakup sejumlah bahasa, seperti javascript, regex, xpath dll. Anda harus mempertimbangkan ini saat membuat fungsi kode Anda jelas.

Alasan 3. Perbedaan dalam suatu bahasa

Misalnya inline VB jika berperilaku berbeda dari jika. Sekali lagi dalam aplikasi modern, kode Anda mungkin bergerak di antara, misalnya kode di belakang dan formulir web inline, Anda harus menyadari perbedaan makna.

Alasan 4. Contoh spesifik Anda nol memeriksa parameter fungsi

Ini adalah contoh yang sangat bagus. Dalam hal itu adalah sesuatu yang dilakukan setiap orang, tetapi sebenarnya merupakan praktik yang buruk ketika Anda memikirkannya.

Ini sangat umum untuk melihat jenis cek karena mengurangi baris kode Anda. Saya ragu ada orang yang akan membawanya dalam tinjauan kode. (dan jelas dari komentar dan penilaian Anda dapat melihatnya populer!)

Namun, itu gagal praktik terbaik karena lebih dari satu alasan!

  1. Its sangat jelas dari berbagai sumber, bahwa praktek terbaik adalah untuk memeriksa parameter untuk validitas sebelum Anda menggunakannya dan melemparkan pengecualian jika mereka tidak valid. Cuplikan kode Anda tidak menunjukkan kode di sekitarnya, tetapi Anda mungkin harus melakukan sesuatu seperti:

    if (smartphone == null)
    {
        //throw an exception
    }
    // perform functionality
    
  2. Anda memanggil fungsi dari dalam pernyataan bersyarat. Meskipun nama fungsi Anda menyiratkan bahwa itu hanya menghitung nilai, itu dapat menyembunyikan efek samping. misalnya

    Smartphone.GetSignal() { this.signal++; return this.signal; }
    
    else if (smartphone.GetSignal() < 1)
    {
        // Do stuff 
    }
    else if (smartphone.GetSignal() < 2)
    {
        // Do stuff 
    }
    

    praktik terbaik akan menyarankan:

    var s = smartphone.GetSignal();
    if(s < 50)
    {
        //do something
    }
    

Jika Anda menerapkan praktik terbaik ini ke kode Anda, Anda dapat melihat bahwa peluang Anda untuk mencapai kode yang lebih pendek melalui penggunaan kondisional tersembunyi menghilang. Praktik terbaik adalah melakukan sesuatu , untuk menangani kasus di mana ponsel cerdas adalah nol.

Saya pikir Anda akan menemukan bahwa ini juga berlaku untuk penggunaan umum lainnya. Anda harus ingat kami juga memiliki:

kondisional sebaris

var s = smartphone!=null ? smartphone.GetSignal() : 0;

dan null koalesensi

var s = smartphoneConnectionStatus ?? "No Connection";

yang menyediakan fungsionalitas panjang kode pendek serupa dengan lebih jelas

banyak tautan untuk mendukung semua poin saya:

https://stackoverflow.com/questions/1158614/what-is-the-best-practice-in-case-one-argument-is-null

Validasi parameter konstruktor dalam C # - Praktik terbaik

Haruskah seseorang memeriksa nol jika dia tidak mengharapkan nol?

https://msdn.microsoft.com/en-us/library/seyhszts%28v=vs.110%29.aspx

https://stackoverflow.com/questions/1445867/why-would-a-language-not-use-short-circuit-evaluation

http://orcharddojo.net/orchard-resources/Library/DevelopmentGuidelines/BestPractices/CSharp

contoh flag kompiler yang mempengaruhi hubungan pendek:

Fortran: "sce | nosce Secara default, kompiler melakukan evaluasi hubung singkat dalam ekspresi logis yang dipilih menggunakan aturan XL Fortran. Menentukan sce memungkinkan kompiler menggunakan aturan Fortran non-XL. Kompilator akan melakukan evaluasi hubung singkat jika aturan saat ini mengizinkannya Defaultnya adalah nosce. "

Pascal: "B - Sebuah flag directive yang mengontrol evaluasi hubung singkat. Lihat Urutan evaluasi operan operator diad untuk informasi lebih lanjut tentang evaluasi hubung singkat. Lihat juga opsi kompilator -sc untuk kompiler baris perintah untuk informasi lebih lanjut ( didokumentasikan dalam Manual Pengguna). "

Delphi: "Delphi mendukung evaluasi hubung singkat secara default. Delphi dapat dimatikan menggunakan arahan kompiler {$ BOOLEVAL OFF}."

Ewan
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Insinyur Dunia