Saya ingin tahu apa yang dianggap cara yang lebih baik untuk kembali ketika saya memiliki if
pernyataan.
Contoh 1:
public bool MyFunction()
{
// Get some string for this example
string myString = GetString();
if (myString == null)
{
return false;
}
else
{
myString = "Name " + myString;
// Do something more here...
return true;
}
}
Contoh 2:
public bool MyFunction()
{
// Get some string for this example
string myString = GetString();
if (myString == null)
{
return false;
}
myString = "Name " + myString;
// Do something more here...
return true;
}
Seperti yang Anda lihat pada kedua contoh, fungsi akan kembali true/false
tetapi apakah ide yang baik untuk meletakkan else
pernyataan seperti pada contoh pertama atau lebih baik tidak meletakkannya?
else
.Jawaban:
Contoh 2 dikenal sebagai blok penjaga. Lebih baik mengembalikan / melempar pengecualian lebih awal jika terjadi kesalahan (parameter salah atau keadaan tidak valid). Dalam aliran logika normal, lebih baik menggunakan Contoh 1
sumber
Gaya pribadi saya adalah menggunakan tunggal
if
untuk blok penjaga, danif
/else
dalam kode pemrosesan metode aktual.Dalam hal ini, Anda menggunakan kondisi
myString == null
sebagai penjaga, jadi saya cenderung menggunakanif
pola tunggal .Pertimbangkan kode yang sedikit lebih rumit:
Contoh 1:
Contoh 2:
Dalam Contoh 1, pelindung dan sisa metode ada di
if
/else
form. Bandingkan dengan Contoh 2, di mana blok penjaga berada dalamif
bentuk tunggal , sedangkan metode lainnya menggunakanif
/else
form. Secara pribadi, saya menemukan contoh 2 lebih mudah dimengerti, sedangkan contoh 1 terlihat berantakan dan terlalu banyak indentasi.Perhatikan bahwa ini adalah contoh yang dibuat-buat dan Anda bisa menggunakan
else if
pernyataan untuk membersihkannya, tapi saya bertujuan untuk menunjukkan perbedaan antara blok penjaga dan kode pemrosesan fungsi yang sebenarnya.Kompiler yang layak harus menghasilkan output yang sama untuk keduanya. Satu-satunya alasan untuk menggunakan satu atau yang lain adalah preferensi pribadi atau untuk menyesuaikan dengan gaya kode yang ada.
sumber
secara pribadi, saya lebih suka metode kedua. Saya merasa seolah itu lebih pendek, lebih sedikit lekukan, dan lebih mudah dibaca.
sumber
Latihan pribadi saya adalah sebagai berikut:
Sebagai contoh:
Sebagai contoh:
Aturan "satu jalan keluar" juga membantu ketika perhitungan membutuhkan sumber daya eksternal yang harus Anda lepaskan, atau menyatakan bahwa Anda harus mengatur ulang sebelum meninggalkan fungsi; terkadang mereka ditambahkan kemudian selama pengembangan. Dengan beberapa pintu keluar di dalam algoritma, jauh lebih sulit untuk memperluas semua cabang dengan benar. (Dan jika pengecualian dapat terjadi, rilis / reset harus diletakkan di blok akhirnya juga, untuk menghindari efek samping dalam kasus luar biasa yang jarang terjadi ...).
Kasing Anda sepertinya termasuk dalam kategori "jalan keluar cepat sebelum pekerjaan nyata", dan saya akan menulisnya seperti versi Contoh 2 Anda.
sumber
Saya lebih suka mempekerjakan penjaga blok di mana pun saya bisa karena dua alasan:
Secara umum saya lebih suka melihat metode di mana fungsi inti dari metode ini jelas dan minimal. Blok penjaga membantu mewujudkan hal ini secara visual.
sumber
Saya suka pendekatan "Fall Through":
Tindakan memiliki kondisi tertentu, yang lainnya hanyalah pengembalian "jatuh melalui" default.
sumber
Jika saya punya satu jika kondisi saya tidak akan menghabiskan terlalu banyak waktu merenungkan gaya. Tetapi jika saya memiliki beberapa kondisi penjaga saya lebih suka style2
Picuture ini. Asumsikan bahwa tes ini rumit dan Anda benar-benar tidak ingin mengikatnya menjadi satu kondisi jika-ORed untuk menghindari kompleksitas:
melawan
Di sini ada dua keunggulan utama
Anda memisahkan kode dalam satu fungsi menjadi dua blok logcal visual: blok validasi (kondisi penjaga) dan blok yang lebih rendah dari kode runnable.
Jika Anda harus menambah / menghapus satu syarat, Anda mengurangi kemungkinan mengacaukan seluruh tangga if-elseif-else.
Keuntungan kecil lainnya adalah Anda memiliki satu set kawat gigi yang lebih sedikit untuk dirawat.
sumber
Ini harus menjadi masalah yang terdengar lebih baik.
mengekspresikan diri dengan lebih baik
untuk metode kecil itu tidak akan banyak perbedaan, tetapi untuk metode senyawa yang lebih besar dapat membuatnya lebih sulit untuk dipahami karena tidak akan terpisah dengan benar
sumber
do something
menyertakan pengembalian. Jika tidak, kode kedua akan dieksekusido somethingelse
terlepas dariif
predikat yang bukan cara kerja blok pertama.Saya menemukan contoh 1 menjengkelkan, karena pernyataan pengembalian yang hilang di akhir fungsi pengembalian nilai segera memicu "Tunggu, ada yang salah" -flag. Jadi dalam kasus seperti ini, saya akan menggunakan contoh 2.
Namun, biasanya ada yang lebih terlibat, tergantung pada tujuan fungsi, misalnya penanganan kesalahan, penebangan, dll. Jadi saya dengan jawaban Lorand Kedves mengenai hal ini, dan biasanya memiliki satu titik keluar pada akhirnya, bahkan pada biaya dari variabel bendera tambahan. Itu membuat pemeliharaan dan ekstensi lebih mudah dalam kebanyakan kasus.
sumber
Ketika
if
pernyataan Anda selalu kembali maka tidak ada alasan untuk menggunakan yang lain untuk kode yang tersisa dalam fungsi. Melakukan hal itu menambah garis ekstra dan lekukan ekstra. Menambahkan kode yang tidak perlu membuatnya lebih sulit untuk dibaca dan seperti semua orang tahu Membaca kode itu Sulit .sumber
Dalam contoh Anda,
else
jelas tidak perlu, TAPI ...Ketika membaca sekilas kode-kode dengan cepat, mata seseorang biasanya melihat kawat gigi dan lekukan untuk mendapatkan gagasan tentang aliran kode; sebelum mereka benar-benar puas dengan kode itu sendiri. Oleh karena itu, menulis
else
, dan menempatkan kawat gigi dan lekukan di sekitar blok kode kedua sebenarnya membuatnya lebih cepat bagi pembaca untuk melihat bahwa ini adalah situasi "A atau B", di mana satu blok atau yang lain akan berjalan. Artinya, pembaca melihat kawat gigi dan lekukan SEBELUM mereka melihatreturn
setelah inisialif
.Menurut pendapat saya, ini adalah salah satu kasus langka di mana menambahkan sesuatu yang berlebihan ke kode sebenarnya membuatnya LEBIH dapat dibaca, tidak kurang.
sumber
Saya lebih suka contoh 2 karena jelas bahwa fungsi mengembalikan sesuatu . Tetapi bahkan lebih dari itu, saya lebih suka kembali dari satu tempat, seperti ini:
Dengan gaya ini saya dapat:
Lihat segera bahwa saya mengembalikan sesuatu.
Tangkap hasil dari setiap pemanggilan fungsi hanya dengan satu breakpoint.
sumber
Gaya pribadi saya cenderung berjalan
Menggunakan pernyataan komentar
else
untuk menunjukkan aliran program dan membuatnya tetap mudah dibaca, tetapi menghindari indentasi besar-besaran yang dapat dengan mudah menjangkau seluruh layar jika banyak langkah yang terlibat.sumber
else
klausa yang disertakan, saya akan memilih yang terakhir karena kompiler akan mengabaikannya secara efektif juga. Meskipun itu akan tergantung padaelse if
tidak meningkatkan lekukan lebih dari asli sekali - jika memang saya setuju dengan Anda. Tapi pilihan saya adalah untuk menjatuhkanelse
sepenuhnya jika gaya itu diizinkan.saya akan menulis
Saya lebih suka gaya ini karena paling jelas saya akan kembali
userName != null
.sumber
myString
hasil yang tidak digunakan . Saya hanya menyalin fungsi dari OP. Saya akan mengubahnya menjadi sesuatu yang terlihat lebih nyata. Tes Boolean itu sepele dan seharusnya tidak menjadi masalah.Aturan praktis saya adalah melakukan if-return tanpa yang lain (sebagian besar untuk kesalahan) atau melakukan rantai if-else-if penuh atas semua kemungkinan.
Dengan cara ini saya menghindari mencoba untuk menjadi terlalu mewah dengan percabangan saya, karena setiap kali saya akhirnya melakukan itu saya menyandikan logika aplikasi ke ifs saya, membuat mereka lebih sulit untuk dipertahankan (Misalnya, jika enum OK atau ERR dan saya menulis semua ifs saya mengambil keuntungan dari fakta itu! OK <-> ERR menjadi susah payah untuk menambahkan opsi ketiga ke enum waktu berikutnya.)
Dalam kasus Anda, misalnya, saya akan menggunakan dataran jika, karena "kembali jika nol" pasti akan menjadi pola umum dan tidak mungkin Anda perlu khawatir tentang kemungkinan ketiga (selain nol / tidak nol) di masa depan.
Namun, jika tes itu adalah sesuatu yang melakukan pemeriksaan lebih mendalam terhadap data, saya akan melakukan kesalahan jika ada yang sebaliknya.
sumber
Saya pikir ada banyak jebakan pada Contoh 2, bahwa di jalan dapat menyebabkan kode yang tidak diinginkan. Fokus pertama di sini didasarkan pada logika yang mengelilingi variabel 'myString'. Oleh karena itu untuk menjadi eksplisit, semua pengujian kondisi harus terjadi dalam akuntansi blok kode untuk logika yang dikenal dan standar / tidak diketahui .
Bagaimana jika nanti kode diperkenalkan secara tidak sengaja ke contoh 2 yang mengubah ouput secara signifikan:
Saya pikir dengan
else
blok segera setelah cek untuk nol akan membuat programmer yang menambahkan perangkat tambahan ke versi masa depan menambahkan semua logika bersama karena sekarang kami memiliki serangkaian logika yang tidak diinginkan untuk aturan asli (mengembalikan jika nilainya adalah batal).Saya meminjamkan kepercayaan saya pada ini banyak ke beberapa pedoman C # pada Codeplex (tautan ke sini: http://csharpguidelines.codeplex.com/ ) yang menyatakan sebagai berikut:
"Tambahkan komentar deskriptif jika blok default (yang lain) seharusnya kosong. Selain itu, jika blok itu tidak seharusnya dicapai, lontarkan InvalidOperationException untuk mendeteksi perubahan di masa mendatang yang mungkin jatuh pada case yang ada. Ini memastikan kode yang lebih baik, karena semua jalur yang dapat dilalui oleh kode telah dipikirkan. "
Saya pikir ini adalah praktik pemrograman yang baik ketika menggunakan blok logika seperti ini untuk selalu memiliki blok default ditambahkan (jika-selain itu, case: default) untuk menjelaskan semua jalur kode secara eksplisit dan tidak membiarkan kode terbuka untuk konsekuensi logika yang tidak diinginkan.
sumber
myString
nilai & kode yang berhasilif
blok adalah logika yang dihasilkan jika string! = Null. Oleh karena itu karena fokusnya adalah pada logika tambahan yang memanipulasi nilai tertentu saya pikir itu harus dienkapsulasi dalam sebuahelse
blok. Kalau tidak, ini membuka potensi ketika saya menunjukkan untuk secara tidak sengaja memisahkan logika & memperkenalkan konsekuensi yang tidak diinginkan. Mungkin tidak terjadi sepanjang waktu, tapi ini benar-benar pertanyaan gaya pendapat praktik terbaik .