Berurusan dengan sup penahan keriting

11

Saya telah memprogram dalam C # dan VB.NET selama bertahun-tahun, tetapi terutama dalam VB. Saya membuat perubahan karier menuju C # dan, secara keseluruhan, saya suka C # lebih baik.

Satu masalah yang saya alami adalah sup keriting. Di VB, setiap kata kunci struktur memiliki kata kunci tutup yang cocok, misalnya:

Namespace ...
    Class ...
        Function ...
            For ...
                Using ...
                    If ...
                        ...
                    End If
                    If ...
                        ...
                    End If
                End Using
            Next
        End Function
    End Class
End Namespace

Kode yang sama yang ditulis dalam C # sangat sulit dibaca:

namespace ... {
    class ... {
        function ... {
            for ... {
                using ... {
                    if ... {
                        ...
                    }
                    if ... {
                        ...
                    }
                }
            }
            // wait... what level is this?
        }
    }
}

Karena sudah terbiasa dengan VB, saya bertanya-tanya apakah ada teknik yang digunakan oleh programmer c-style untuk meningkatkan keterbacaan dan untuk memastikan bahwa kode Anda berakhir di "blok" yang benar. Contoh di atas relatif mudah dibaca, tetapi kadang-kadang di akhir sepotong kode saya akan memiliki 8 atau lebih tingkat kurung kurawal, mengharuskan saya untuk menggulir ke atas beberapa halaman untuk mengetahui penjepit mana yang mengakhiri blok saya tertarik di.

JDB masih ingat Monica
sumber
83
Saya tahu ini mungkin terdengar khotbah, dan mungkin Anda memiliki kondisi khusus yang mengharuskannya (karena ya, kadang - kadang diperlukan - untungnya saat-saat seperti itu jarang terjadi), tetapi biasanya "... 8 atau lebih tingkat kurung kurawal, mengharuskan saya untuk menggulir beberapa halaman untuk mengetahui penjepit mana yang mengakhiri blok saya tertarik " berarti kode perlu beberapa refactoring serius dan pembersihan.
FrustratedWithFormsDesigner
7
Satu hal yang saya lihat sudah selesai, dan saya harus lakukan, adalah pada akhir kurung kurawal, saya akan menambahkan komentar tentang hal itu. Sesuatu seperti // End's using X statement.
PiousVenom
14
@FrustratedWithFormsDesigner sangat memperhatikan fakta bahwa aliran kontrol Anda berantakan dan perlu diulang. Yang mengatakan, saya pikir Anda lebih banyak mengeluh tentang kurung kurawal daripada pelingkupan dan saya akan mengatakan Anda hanya perlu terbiasa dengan itu. Mempelajari bahasa dengan sintaksis yang sangat berbeda dari yang biasa Anda gunakan tampak seperti sup untuk sementara waktu, tetapi dengan latihan yang hilang. Anda hanya perlu bekerja keras dan menangani sampai otak Anda mulai memproses sintaksis secara lebih alami, Anda akan sampai di sana.
Jimmy Hoffa
2
@FrustratedWithFormsDesigner - Saya perlu membersihkan banyak objek COM dalam situasi interop COM. Saya menggunakan teknik yang disarankan dalam artikel ini: jake.ginnivan.net/vsto-com-interop . Ini dengan mudah membuat dua atau tiga lapisan. Ketika Anda menumpuk for loop, fungsi, kelas dan namespace di atas itu (bersama dengan pernyataan if), Anda dengan mudah mendapatkan beberapa lapisan kawat gigi.
JDB masih ingat Monica
5
@ TyrionLannister - Dan itu bisa menjadi beberapa komentar tercepat untuk tidak sinkron dengan milik mereka ... Saya pikir jika saya akan memiliki sesuatu seperti itu, saya lebih suka itu dibuat secara otomatis (pada tampilan -waktu saja, tidak bertahan) oleh IDE.
Clockwork-Muse

Jawaban:

39

Letakkan brace keriting awal Anda di "peringkat" yang sama dengan yang akhir Anda, seperti ini:

namespace ... 
{
    class ... 
    {
        function ... 
        {
            for ... 
            {
                using ... 
                {
                    if ... 
                    {
                        ...
                    }
                    if ... 
                    {
                        ...
                    }
                }
            }
            // It's the `function` level!
        }
    }
}
Robert Harvey
sumber
15
Saya setuju. Kurung Mesir membuat saya sakit kepala.
PiousVenom
8
Juga, sebagian besar IDE (mungkin) menyorot mitra penjepit ketika Anda mengkliknya.
StuperUser
3
@ TyrionLannister: Terima kasih karena akhirnya memberi saya istilah untuk gaya itu! Saya tidak pernah memiliki nama baik untuk mereka selain dari "kawat gigi yang tidak rata".
FrustratedWithFormsDesigner
3
@ Cyborgx37: Apakah IDE Anda memiliki fitur "Go to matching brace"? Biasanya terikat pada pintasan kunci yang secara otomatis memindahkan kursor Anda ke penjepit yang cocok dengan yang sedang disorot.
FrustratedWithFormsDesigner
3
Harus berkata, saya tidak melihat bagaimana ini membuatnya lebih mudah. Bagaimanapun Anda hanya melihat layar pada tingkat indentasi penjepit sampai Anda mendapatkan kata kunci. Dan dengan semua garis ekstra itu, Anda sekarang harus mencari lebih jauh.
Blorgbeard keluar
14
  • Bergantung pada IDE Anda: letakkan kursor Anda pada kurung buka / tutup dan itu akan menyoroti itu dan kurung yang sesuai.
  • Perkecil blok dan ini menunjukkan di mana ia membuka / menutup.
  • Tulis blok kode yang lebih kecil. Serius. Lihat Clean Code, dan jangan pernah mengalami masalah ini lagi (dan memiliki lebih banyak kode yang dapat dibaca / dikelola).

Satu catatan, berikut ini adalah sintaksis c # yang valid yang mungkin membantu situasi khusus Anda:

using (var type = new MyDisposable1())
using (var type2 = new MyDisposable2())
{
    /* do what you will with type2 and type2 */
}
Steven Evers
sumber
Berburu untuk karakter yang disorot adalah yang mendorong saya untuk memposting pertanyaan ini di tempat pertama.
JDB masih ingat Monica
2
@ Cyborgx37: Oleh karena itu, point 3. Jika seluruh blok kode Anda cocok di layar, Anda tidak perlu berburu. Di sebagian besar / semua kelas yang saya tulis, satu-satunya pasang kawat gigi yang tidak pas di layar adalah namespace / kelas.
Steven Evers
Apa yang Anda sarankan dalam poin 1 & 2 adalah apa yang saya lakukan sekarang ... tetapi ini mengharuskan saya meninggalkan tempat saya mengkode dan mulai memanipulasi pandangan saya tentang kode untuk mencari tahu di mana harus meletakkan baris berikutnya. Poin 3 diambil dengan baik, tetapi tidak selalu memungkinkan, terutama jika kode Anda memerlukan beberapa lapisan usingblok (lihat jake.ginnivan.net/vsto-com-interop )
JDB masih mengingat Monica
@ Cyborgx37: Lihat hasil edit saya.
Steven Evers
1
@ Cyborgx37 Jika Anda memilih warna yang menonjol dari yang lainnya (saya menggunakan latar belakang ungu dan teks putih untuk sementara waktu, IIRC) maka tidak perlu berburu untuk penjepit yang cocok - itu praktis menjerit pada Anda "Aku DI SINI ! ".
CVn
5

Konvensi umum adalah menambahkan komentar setelah kurung kurawal untuk menunjukkan struktur yang ditutup:

if {
   ...
} // end if

while (condition) {
   ...
} // end while

dll. Saya sendiri tidak pernah melakukan pemanasan pada konvensi ini, tetapi beberapa orang merasa terbantu.

John Bode
sumber
16
Saya telah melihat orang melakukan ini, dan ketika mereka bertukar / mengubah awal blok (mengubah whileke for, bertukar ke ifpernyataan) mereka hampir TIDAK PERNAH ingat untuk memperbarui komentar penutup, membuat mereka lebih buruk daripada tidak berguna. Konvensi ini mungkin hanya akan berguna jika Anda bisa memaksakan diri untuk mempertahankan komentar setiap kali sifat dari pencocokan {berubah.
FrustratedWithFormsDesigner
Ya, saya sudah melakukan beberapa hal, tapi ini banyak pekerjaan tambahan (dan kebisingan). Saya berharap akan ada sesuatu yang lebih mudah.
JDB masih mengingat Monica
5
Komentar seharusnya hanya menjelaskan mengapa tidak pernah bagaimana atau bagaimana kode melakukan keduanya dan mengandalkan komentar untuk menjelaskan salah satu dari mereka berarti kode itu sulit dibaca yang merupakan tanda kode harus diperbaiki tidak dikomentari.
Jimmy Hoffa
1
Ini membuat saya bertanya-tanya mengapa tidak ada yang menulis editor yang menampilkan komentar ini, tetapi tidak benar-benar memasukkannya ke dalam kode ..
Brendan Long
2
@JimmyHoffa: Saya pikir aturan yang lebih baik untuk komentar adalah bahwa mereka harus memberikan kejelasan . Biasanya itu berarti menjawab "mengapa", tetapi bisa juga berarti hal lain. Jangan terlalu terjebak dalam dogma sehingga menghentikan Anda dari melakukan hal-hal yang benar-benar membantu, seperti sesekali menambahkan komentar ke penjepit penutup yang jauh dari penjepit pembuka.
Bryan Oakley 8-12
5

Secara umum, ketika menjadi sulit untuk mencocokkan kawat gigi dalam gaya apa pun - itu mungkin berarti metode ini terlalu panjang dan harus difaktorkan ulang.

MaximR
sumber
5

Saya pikir Anda perlu tangguh dengan kawat gigi. Akhirnya mereka akan menjadi kebiasaan bagi Anda dan Anda akan bertanya-tanya bagaimana Anda bisa hidup tanpanya.

Pastikan mereka diberi indentasi dengan benar, dan bahwa beberapa konvensi spasi sedang diikuti (tidak masalah yang mana).

MrFox
sumber
Setahun kemudian, dan saran ini berdering benar. :)
JDB masih mengingat Monica
4

Saya menghapus 2 level bersarang dengan menciutkan namespace dan cakupan kelas secara horizontal. Perhatikan metode yang rata dengan tepi kiri layar. Saya tidak melihat gunanya kehilangan 2 level indentasi di setiap file.

Setelah itu jarang Anda akan memiliki kedalaman lebih dari 4 level.

namespace FooNameSpace {
class Foo {

public void bar()
{
    while(true)
    {
        while(true)
        {
            break;
        }
    }
}

public void fooBar()
{
    foreach(var item in FooList)
    {
        foreach(var b in item.Bars)
        {
            if(b.IsReady)
            {
                bar();
            }
            bar();
        }
        bar();
    }
}

}}//end class, namespace
mike30
sumber
Saya suka ide ini, tetapi Visual Studio tampaknya tidak mendukungnya (setidaknya, 2008. Kami akan memperbarui ke 2012 pada akhir tahun, jadi inilah harapan)
JDB masih mengingat Monica
@ Cyborgx37. Saya mengedit teks secara eksternal di VIM sehingga tidak masalah. Tetapi dalam Visual Studio lakukan: Kontrol + A, lalu tekan tombol "indent less". Hanya lakukan untuk file baru. Jangan repot-repot dengan file yang ada karena akan mengacaukan perbandingan dalam kontrol sumber.
mike30
Mengetik dalam kurung tutup / kurung memulai format otomatis oleh VS tetapi Anda selalu dapat menekan CTRL + z untuk menolak sarannya.
Alex In Paris
1

Saya baru-baru ini memutuskan untuk mencoba dan meresmikan dua aturan tentang konstruksi kontrol aliran yang pada dasarnya seperti ini:

  • Anda seharusnya tidak memiliki apa pun kecuali konstruksi aliran kode yang diperlukan
  • Anda harus membuat konstruksi aliran kode sekecil mungkin

Untuk alasan persisnya yang telah Anda sebutkan dan sadari, saya pikir ini adalah aturan yang bagus untuk diikuti. Ada beberapa teknik sederhana yang dapat Anda terapkan untuk mencapainya:

  • Keluar dari ruang lingkup sesegera mungkin (ini termasuk ruang lingkup loop serta fungsi)
  • Perhatikan elses yang dapat dikurangi dengan keluar dari fungsi sebelumnya jika dan menerapkan teknik keluar lingkup seperti yang saya sebutkan
  • Membalikkan pemeriksaan bersyarat Anda ketika kode di dalam if lebih besar dari itu di luar
  • Kode faktor di dalam loop ke metode lain ketika ukuran loop tumbuh untuk mengaburkan sisa metode
  • Perhatikan setiap lingkup yang hanya berisi ruang lingkup lain, misalnya fungsi yang seluruh ruang lingkupnya diisi oleh if dengan tidak ada yang di luar if

Saya merinci di sini contoh bagaimana tidak mengikuti ini dapat berakhir dengan Anda melakukan seperti yang Anda katakan dan meletakkan kode di blok kode yang salah, yang buruk dan penyebab mudah bug muncul selama pemeliharaan.

Jimmy Hoffa
sumber
Terima kasih, mungkin ada satu atau dua blok yang bisa saya refactor. Ini akan membantu, tetapi sulit untuk memperbaiki beberapa usingblok bersarang .
JDB masih ingat Monica
@ Cyborgx37 sebenarnya menggunakan blok dapat diuraikan jika mereka bersarang memenuhi cakupan, lihat di sini stackoverflow.com/questions/1329739/... itu pada dasarnya bekerja seperti kontrol aliran garis tunggal mengkonstruksikan bagaimana Anda dapat jika (benar) doSomething (); Anda juga dapat if (true) if (somethingElse) if (otherThings) {doThis (); lakukan itu(); lakukan Apa pun (); } dan sarang seandainya seperti yang Anda harapkan (JANGAN MENULIS KODE SEPERTI YANG UNTUK CINTA ALLAH, HANYA MELAKUKANNYA DENGAN PENGGUNAAN DAN TIDAK ADA LAIN heh)
Jimmy Hoffa
Ya, saya tahu tentang bersarang menggunakan blok, tetapi ini hanya berfungsi jika Anda memiliki satu baris di bawahnya. Di sebagian besar kode saya, itu tidak terjadi. Masih posting yang sangat membantu secara keseluruhan ... belajar beberapa hal (+1)
JDB masih ingat Monica
@ Cyborgx37 ya saya menyadari lingkup bersarang hanya berfungsi jika Anda tidak memiliki bit tambahan, yang mengatakan apakah ada pola cara penggunaan Anda? Apakah mungkin untuk memindahkan sebagian ekstra ke konstruktor jika itu di atas atau pembuangan jika itu di bagian bawah? Itu jika itu terpola; menebak mungkin karena Anda mengemukakan ini sebagai masalah, jadi Anda mungkin sering menggunakan sarang ini dalam kode Anda.
Jimmy Hoffa 8-12
Saya sebenarnya sudah mulai bekerja pada implementasi Factory-pattern yang membungkus objek COM dalam kelas "AutoCleanup". Saya kemudian menggunakan satu usingpernyataan di kelas pabrik dan, ketika dibuang, secara otomatis membuang semua kelas yang dibungkus. Ini berfungsi dengan baik sejauh ini dan telah secara signifikan mengurangi jumlah usingpernyataan dalam kode saya.
JDB masih mengingat Monica
1

Sayangnya, ini adalah salah satu penyebab peperangan tertua dalam komputasi. Argumen yang masuk akal dapat dibuat dari kedua belah pihak (ekonomi real-estate vertikal yang lebih baik versus kemampuan yang lebih mudah untuk mencocokkan brace pembuka secara visual dengan brace penutup), tetapi dalam kenyataannya format-kode sumber sederhana akan menyelesaikan segalanya untuk Anda. MS Visual C # memiliki satu built in yang berfungsi dengan baik.

Namun berhati-hatilah bahwa jika Anda bekerja sebagai bagian dari tim, Anda akan diharapkan untuk menyesuaikan diri dengan konvensi yang digunakan oleh tim itu, sehingga membayar untuk mendapatkan keakraban dengan kedua gaya dan menahan diri dari menjadi religius atas gaya penyangga.

Jadi sementara Anda belajar, tentu saja, fokuslah pada gaya yang membuatnya lebih mudah bagi Anda untuk belajar, tetapi tetap awasi yang lain saat Anda melakukannya dan Anda akan baik-baik saja.

Maximus Minimus
sumber
1
Saya tidak yakin apakah itu adalah formatter default atau sesuatu di ReSharper, tetapi ketika saya menggunakan C #, kami memiliki opsi yang memformat ulang kode sebagai bagian dari check-in. Dengan begitu Anda bisa memformat kode sesuai keinginan Anda saat bekerja dengannya, tetapi akan diformat ulang ke "standar proyek" pada saat check-in. Saya pikir satu-satunya standar format yang kami miliki adalah menggunakan spasi alih-alih tab.
TMN
1

Gunakan Resharper, yang akan membantu merekomendasikan cara untuk mengurangi sarang. Juga, baca buku Clean Code dari Bob Martin , yang menekankan bahwa suatu fungsi seharusnya hanya melakukan satu hal, dan oleh karena itu setiap fungsi hanya memiliki panjang setengah lusin baris, sehingga Anda tidak perlu khawatir tentang banyak tingkat sarang.

lorddev
sumber
1

Ada add-on untuk editor yang dapat membantu Anda di: C # Outline .

Add-on memperluas editor VS20xx untuk C # dengan menambahkan fitur untuk menutup, memperluas dan menyoroti blok kode bersarang. Fitur-fitur ini memungkinkan pengeditan dan pembacaan konten blok kode yang bersarang seperti jika, sementara, dll.

Tidak mungkin
sumber
0

Jika Anda menulis Kode di Visual Studio, ada juga Plugin yang menunjukkan Anda titik-titik vertikal antara awal dan akhir setiap struktur yang Anda buat.

Tapi secara keseluruhan saya pikir itu hanya akan memakan waktu sampai Anda terbiasa dengan "Curly-Braces-Soup". (Btw, aku sangat suka ungkapan itu. Kedengarannya agak seperti Episode-Name untuk The Big Bang Theory)

jam
sumber
0

Lekukan memberi tahu Anda di mana Anda berada, dalam kedua gaya sintaksis. Jika Anda menulis program VB atau program C # pada satu baris, Anda akan segera tidak dapat mengetahui di mana di sintaks bersarang Anda. Mesin mem-parsing frasa akhir blok atau kurung kurawal, tetapi manusia membutuhkan lekukan.

Frasa pemblokiran akhir berasal dari era kartu berlubang dan pita kertas, ketika pemrograman kurang interaktif dan visual. Atau, sungguh, tidak interaktif sama sekali. Itu sulit untuk memasukkan program, dan programmer membutuhkan kompiler untuk menjadi sangat pintar tentang analisis sintaksis dan pemulihan kesalahan.

Di masa lalu, siklus sunting-kompilasi-lari mungkin melibatkan mempersiapkan kartu berlubang dengan pemukul kartu, dan kemudian berbaris ke jendela pengajuan pekerjaan di mana petugas mengambil kartu-kartu yang dilubangi dan menyerahkannya ke mesin. Kemudian, programmer akan mengumpulkan output (dicetak di atas kertas) dari jendela lain. Jika program memiliki kesalahan, output hanya akan terdiri dari diagnostik kompiler. Ketika waktu penyelesaian yang lama, biaya tambahan mengetik end ifbukan hanya )dibenarkan jika membantu meningkatkan kualitas diagnostik, karena programmer harus memperbaiki kesalahan sebanyak mungkin dalam satu iterasi tunggal untuk mengurangi jumlah waktu yang terbuang. iterasi melalui jendela pengiriman pekerjaan.

Ketika kurung kurawal penutupan hilang, sulit untuk mengatakan mana kurung kurawal terbuka yang tidak ditutup. (Kompilator mungkin harus mengurai indentasi untuk membuat tebakan yang terpelajar.) Jika Anda menghapus kurung kurawal di dalam suatu fungsi, maka sepertinya seluruh sisa file adalah bagian dari fungsi itu, yang mengakibatkan kesibukan pesan kesalahan yang tidak membantu. Sedangkan jika Anda memiliki end functionsintaks, kompiler dapat menyimpulkan di mana fungsi yang salah berakhir, memulihkan, dan menguraikan fungsi berikutnya dengan benar, memberi Anda diagnostik tambahan, jika ada, yang bermakna.

Ketika Anda bekerja di editor teks yang sadar kode yang secara otomatis mengindentasi dan mewarnai kode Anda, pada layar resolusi tinggi di mana Anda dapat melihat enam puluh atau lebih baris, argumen untuk jenis bahasa canggung itu tidak lagi berlaku. Anda dapat mengedit dan membangun kembali program secara bertahap secara bertahap sehingga Anda dapat menangani satu kesalahan sekaligus. Selain itu, dengan melihat bagian besar dari program secara bersamaan di layar dan mempertahankan lekukan yang tepat, Anda dapat mengurangi terjadinya jenis kesalahan bersarang di tempat pertama. Dan editor teks pemrograman yang baik bahkan akan menandai beberapa jenis kesalahan sintaks saat Anda mengetik. Terlebih lagi, ada editor lipat yang akan menciutkan blok program berdasarkan sintaksnya, memberikan tampilan "seperti garis besar" dari strukturnya.

Lisp menggunakan tanda kurung dari awal dan mungkin, bukan kebetulan, peretas Lisp memelopori pemrograman sebagai pengalaman interaktif dengan membangun sistem yang menerima program dalam potongan kecil (ekspresi).

Bahkan, Anda tidak perlu mengakhiri simbol sama sekali, seperti yang diilustrasikan oleh bahasa Python. Identation hanya bisa menjadi struktur. Manusia sudah menggunakan lekukan untuk mendapatkan struktur kode bahkan dalam bahasa di mana mesin bergantung pada simbol atau frasa berakhir.

Kaz
sumber
-1

Jika Anda menggunakan IDE, Cukup tekan Crtl+ k+ Ddan IDE akan melakukan pekerjaan selanjutnya.

Jagz W
sumber
yang gerhana IDE menggunakan ctrl-shift-i untuk lekukan dan ctrl-shift-f untuk memformat
ratchet freak
check-in di studio visual
Jagz W