Kıvırcık ayraç çorbası ile başa çıkmak


11

Yıllarca hem C # hem de VB.NET'te programladım, ancak öncelikle VB'de. C # 'a doğru bir kariyer değişikliği yapıyorum ve genel olarak C #' ı daha iyi seviyorum.

Yine de yaşadığım bir konu kıvırcık süslü çorba. VB'de, her bir yapı anahtar kelimesinin eşleşen bir yakın anahtar kelimesi vardır, örneğin:

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

C # 'da yazılan kodun okunması çok zor:

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

VB için çok alışkın olmak, c-tarzı programcılar tarafından okunabilirliği artırmak ve kodunuzun doğru "blokta" bitmesini sağlamak için kullanılan bir teknik olup olmadığını merak ediyorum. Yukarıdaki örneği okumak nispeten kolaydır, ancak bazen bir kod parçasının sonunda, ilgilendiğim bloğu bitirdiğini anlamak için birkaç sayfayı yukarı kaydırmamı gerektiren 8 veya daha fazla kıvırcık parantezim olacak. içinde.


83
Bunun kulağa garip gelebileceğini biliyorum, ve belki de bunu gerektiren özel koşullarınız var (çünkü evet, bazen gerekli - neyse ki bu tür zamanlar nadir olmalı), ama genellikle "... 8 veya daha fazla seviyeli kıvırcık parantez, kaydırmamı gerektirir hangi ayracı ilgilendiğim bloğu bitirdiğini anlamak için birkaç sayfa yukarı " kod bazı ciddi yeniden düzenleme ve temizleme ihtiyacı anlamına gelir.
SinirliWithFormsDesigner

7
Yaptığım ve yaptığım bir şey, kıvırcık bir ayraç sonunda, bunun hakkında bir yorum ekleyeceğim. Gibi bir şey // End's using X statement.
PiousVenom

14
@FrustratedWithFormsDesigner, kontrol akışınızın dağınık olması ve yeniden yapılması gerektiği gerçeğine dikkat çekiyor. Bununla birlikte, kıvırcık kaşlı ayraçlardan kapsamdan daha fazla şikayetçi olduğunuzu düşünüyorum ve sadece buna alışmanız gerektiğini söyleyebilirim. Bir süreliğine çorbaya benzemek için alışık olduğunuzdan çok farklı bir sözdizimine sahip bir dil öğrenmek, ancak pratikte ortadan kalkar. Beyniniz sözdizimini daha doğal bir şekilde işlemeye başlayana kadar tokalaşmanız ve uğraşmanız yeterlidir, oraya gidersiniz.
Jimmy Hoffa

2
@FrustratedWithFormsDesigner - Bir COM birlikte çalışma durumunda bir sürü COM nesnesini temizlemem gerekiyor. Bu makalede önerilen tekniği kullanıyorum: jake.ginnivan.net/vsto-com-interop . Bu kolayca iki veya üç katman oluşturur. Bunun için for döngüsünü, işlevini, sınıfını ve ad alanını (if ifadesiyle birlikte) yığınladığınızda, kolayca parantez katmanlarına kolayca ulaşabilirsiniz.
JDB hala Monica

5
@TyrionLannister - Ve bunlar ait oldukları şeyle senkronizasyondan çıkmak için en hızlı yorumlardan bazıları olabilir ... Sanırım böyle bir şeye sahip olsaydım, otomatik olarak oluşturulmasını tercih ederim (ekranda) - yalnızca zaman, kalıcı değil).
Clockwork-Muse

Yanıtlar:


39

Kıvırcık parantezinizi bitişinizle aynı "rütbe" ye koyun, şöyle:

namespace ... 
{
    class ... 
    {
        function ... 
        {
            for ... 
            {
                using ... 
                {
                    if ... 
                    {
                        ...
                    }
                    if ... 
                    {
                        ...
                    }
                }
            }
            // It's the `function` level!
        }
    }
}

15
Katılıyorum. Mısır parantezleri başım ağrıyor.
PiousVenom

8
Ayrıca, çoğu IDE (muhtemelen) bir küme ayrağının ortağını tıkladığınızda vurgulamaktadır.
StuperUser

3
@TyrionLannister: Sonunda bana bu tarz için bir terim verdiğiniz için teşekkürler! Onlar için "yanlış hizalanmış diş telleri" dışında hiçbir zaman iyi bir ismim yoktu.
SinirliWithFormsDesigner

3
@ Cyborgx37: IDE'nizde "Eşleşen ayraca git" özelliği var mı? Genellikle imlecinizi o anda vurgulanan köşeli parantezle otomatik olarak hareket ettiren bir tuş kısayoluna bağlıdır.
SinirliWithFormsDesigner

3
Söylemeliyim ki, bunun bunu nasıl kolaylaştırdığını anlamıyorum. Her iki durumda da, bir anahtar kelimeye ulaşana kadar ekrana küme ayracı girintisi düzeyinde bakabilirsiniz. Ve tüm bu ekstra çizgilerle artık daha fazla bakmanız gerekiyor.
Blorgbeard

14
  • IDE'nize bağlı olarak: imlecinizi açma / kapama ayracı üzerine getirdiğinizde, hem bunu hem de karşılık gelen ayracı vurgulayacaktır.
  • Bloğu daraltın ve nerede açıldığını / kapandığını gösterir.
  • Daha küçük kod blokları yazın. Ciddi anlamda. Kontrol edin Clean Codeve bu sorunla bir daha asla karşılaşmayın (ve daha okunabilir / bakımı kolay kodlara sahip olun).

Bir not, aşağıdaki özel durumunuza yardımcı olabilecek geçerli c # sözdizimidir:

using (var type = new MyDisposable1())
using (var type2 = new MyDisposable2())
{
    /* do what you will with type2 and type2 */
}

Vurgulanan tek karakter için avcılık, bu soruyu ilk etapta göndermem için beni yönlendirdi.
JDB hala Monica

2
@ Cyborgx37: Dolayısıyla 3. nokta. Kod bloğunuzun tamamı ekrana sığarsa, asla avlanmak zorunda kalmazsınız. Yazdığım sınıfların çoğunda / hepsinde, ekrana sığmayan tek ayraç çiftleri ad alanı / sınıftır.
Steven Evers

Nokta 1 ve 2'de önerdiğim şey şu an yaptığım şey ... ama bu, kodladığım yerden ayrılmamı ve bir sonraki satırı nereye koyacağımı anlamak için kod görüşümü değiştirmeye başlamamı gerektiriyor. Nokta 3 iyi alınmış, ancak her zaman mümkün değildir, özellikle de kodunuz birkaç usingblok katmanı gerektiriyorsa (bkz. Jake.ginnivan.net/vsto-com-interop )
JDB hala Monica

@ Cyborgx37: Düzenlememi görün.
Steven Evers

1
Eğer diğerlerinden öne çıkıyor bir renk seçerseniz Cyborgx37 @ sonra eşleşen ayracı için ava gerek yoktur (bir süre IIRC için mor arka plan ve beyaz metin kullanılır) - Eğer "Ben de pratikte SCREAMS BURADA ! ".
CVn

5

Yaygın bir kural, kapandığı yapıyı belirtmek için kapanış ayracı sonrasında bir yorum eklemektir:

if {
   ...
} // end if

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

Bu konvansiyona hiç ısınmadım, ama bazı insanlar bunu yararlı buluyor.


16
İnsanların bunu gördük ve bunlar takas zaman / (a değiştirmek bloğun başlangıç değiştirmek gelmiş whilebir etmek foriçin, takas ifda beyanlar) neredeyse ASLA onları render kapanış yorumlarınızı güncelleştirmeyi unutmayın kötü yararsız daha. Bu kural muhtemelen, ancak eşleşen {değişikliklerin her doğasında yorumları korumaya zorlayabiliyorsanız faydalı olacaktır .
FrustratedWithFormsDesigner

Evet, bunlardan bazılarını yaptım, ama çok fazla iş (ve gürültü). Daha basit bir şey olmasını umuyordum.
JDB hala Monica

5
Yorumlar yalnızca açıklamalıdır neden asla neyi ya nasıl kod ya bunların yorumların olanlar ve güvenmek hem açıklamaya yapan kod kod değil yorumladı düzeltilmelidir bir işaret olduğu okumak zordur anlamına gelir.
Jimmy Hoffa

1
Bu neden kimse bu yorumları görüntüleyen bir editör yazmamış, ama aslında onları kodda içermiyor merak ediyor ..
Brendan Long

2
@JimmyHoffa: Bence yorumlar için daha iyi bir kural, netlik sağlamalarıdır . Genellikle bu "neden" yanıtı vermek anlamına gelir, ama aynı zamanda başka şeyler anlamına da gelebilir. Dogma'da o kadar yakalanmayın ki, bazen açılış braketinden çok uzak olan bir kapanış parantezine yorum eklemek gibi, gerçekten yardımcı olan şeyleri yapmanıza engel olur.
Bryan Oakley

5

Genel olarak, herhangi bir tarzda kaşlı ayraçları eşleştirmek zorlaştığında - muhtemelen yöntemin çok uzun olduğu ve yeniden faktörlendirilmesi gerektiği anlamına gelir.


5

Bence parantez ile zorlamanız gerekiyor. Sonunda size ikinci bir doğa olacaklar ve onlar olmadan nasıl yaşadığınızı merak edeceksiniz.

Yine de uygun şekilde girintili olduklarından ve bazı boşluk kurallarına uyulduğundan emin olun (hangisinin önemli olmadığı).


Bir yıl sonra ve bu tavsiye doğru. :)
JDB hala Monica

4

Ad alanını ve sınıf kapsamlarını yatay olarak daraltarak 2 düzey iç içe yerleştirme düzeyini kaldırırım. Yöntemlerin ekranın sol kenarıyla aynı hizada olduğuna dikkat edin. Her dosyada 2 girinti seviyesini kaybetmenin anlamını görmüyorum.

Bundan sonra 4 seviyeden daha derin iç içe olacaksınız.

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

Bu fikri beğendim, ancak Visual Studio bunu desteklemiyor gibi görünüyor (en azından 2008. Yıl sonuna kadar 2012'ye yükseltiyoruz, bu yüzden umuyoruz)
JDB hala Monica'nın

Cyborgx37 @. VIM'de metni harici olarak düzenliyorum, bu yüzden sorun değil. Ancak Visual Studio'da şunları yapın: Control + A, ardından "daha az girinti" düğmesine basın. Yalnızca yeni dosyalar için yapın. Mevcut dosyalar ile uğraşmayın, çünkü kaynak kontrolündeki fark karşılaştırmaları bozacaktır.
mike30

Kapatma parantezlerini / kaşlı ayraçları yazmak, VS tarafından otomatik bir format başlatır, ancak önerisini reddetmek için her zaman CTRL + z tuşlarına basabilirsiniz.
Alex In Paris

1

Son zamanlarda, akış kontrolü yapıları hakkında temelde şu şekilde giden iki kuralı resmileştirmeye karar verdim:

  • Gerekli kod akışı yapılarından başka bir şeye sahip olmamalısınız
  • Kod akışı yapılarını mümkün olduğunca küçük yapmalısınız

Tam olarak bahsettiğiniz ve açıkça farkında olduğunuz nedenlerden dolayı, bunların takip edilmesi gereken harika kurallar olduğunu düşünüyorum. Bunları gerçekleştirmek için kullanabileceğiniz birkaç basit teknik vardır:

  • En kısa sürede kapsamdan çıkın (bu, işlevlerin yanı sıra döngülerin kapsamını da içerir)
  • Bahsettiğim gibi kapsamdan çıkma tekniğinden önceki işlevden çıkılarak hafifletilebilecek başkaları izleyin ve uygulayın
  • Bir if içindeki kod dışarıdakinden daha büyük olduğunda koşullu denetimlerinizi tersine çevirin
  • Döngünün boyutu, yöntemin geri kalanını gizlemek için büyüdüğünde, başka bir yönteme giden bir döngü içindeki faktör kodu
  • Yalnızca başka bir kapsam içeren kapsamlara dikkat edin; örneğin, kapsamı if ile hiçbir şey olmadan bir if ile doldurulan bir işlev

Burada , bunlara uymamanın nasıl söylediğiniz gibi sonuçlanabileceği ve yanlış kod bloğuna kod koyabileceğinizle ilgili örnekler verdim , bu da kötü ve bakım sırasında ortaya çıkan hataların kolay bir nedeni.


Teşekkürler, yeniden düzenleyebileceğim bir ya da iki blok olabilir. Bu yardımcı olacaktır, ancak birkaç iç içe usingblokları yeniden düzenlemek zor .
JDB hala Monica

@ Cyborgx37 aslında blokları kullanarak, kapsamları yerine getirdiyse satır içine alınabilir, buraya bakın stackoverflow.com/questions/1329739/… temel olarak tek satır akış kontrol yapıları gibi çalışır (do) doSomething (); ayrıca (true) if (somethingElse) if (otherThings) {doThis (); yap bunu(); ne istersen yap(); } ve ifs beklediğiniz gibi yuva (TANRI SEVGİSİ İÇİN GİBİ KOD YAZMAYIN, SADECE BU KULLANIM VE HİÇBİR ŞEY İLE YAPMAYIN)
Jimmy Hoffa

Evet, blokları kullanarak iç içe yerleştirmeyi biliyorum, ancak bu sadece altında tek bir satır varsa işe yarar. Kodumun çoğunda, durum böyle değil. Hala çok yararlı bir yazı genel ... birkaç şey öğrendim (+1)
JDB hala Monica

@ Cyborgx37 evet kapsamı iç içe yerleştirmenin sadece fazladan bitleriniz yoksa işe yarar olduğunun farkındayım, bu da kullanıcılarınızın tarzına bir model olduğunu söyledi? Üstte ise bu ekstradan bir kısmını kurucuya, altta ise elden çıkarmak mümkün olabilir mi? Bu desenli ise; bunun bir sorun olarak ortaya çıkmasından bu yana tahmin edilebilir, bu nedenle muhtemelen kodlarınızda genellikle yuvaları kullanarak bunlara rastlarsınız.
Jimmy Hoffa

Aslında COM nesneleri bir "AutoCleanup" sınıfında sarar bir Factory-pattern uygulaması üzerinde çalışmaya başladım. Daha sonra usingfabrika sınıfında tek bir ifade kullanıyorum ve elden çıkarıldığında, otomatik olarak tüm sarılmış sınıfları atıyor. Şimdiye kadar iyi çalışıyor ve kodumdaki usingifadelerin sayısını önemli ölçüde azalttı .
JDB hala Monica

1

Maalesef bu, bilgi işlemdeki en eski savaş nedenlerinden biridir. Makul argümanlar her iki taraftan da yapılabilir (daha iyi dikey gayrimenkul ekonomisi ve açılış ayracı kapanış ayracı ile görsel olarak daha kolay eşleştirme yeteneği), ancak gerçekte basit bir kaynak kodu formatlayıcı sizin için her şeyi çözecektir. MS Visual C #, iyi çalışan bir tane var.

Bununla birlikte, bir takımın parçası olarak çalışıyorsanız, o takımın kullandığı sözleşmelere uymanız beklenir, bu nedenle her iki stile de aşina olmak ve brace stilleri üzerinde dini olmaktan kaçınmak için ödeme yaparsınız.

Bu yüzden öğrenirken elbette öğrenmenizi kolaylaştıran stile odaklanın, ancak siz öndeyken diğer tarafa yarım göz atın ve iyi olacaksınız.


1
Varsayılan biçimlendirici veya ReSharper'da bir şey olup olmadığından emin değilim, ancak C # kullandığımda check-in'nin bir parçası olarak kodu yeniden biçimlendiren bir seçenek ayarladık. Bu şekilde, kod üzerinde çalışırken istediğiniz şekilde biçimlendirebilirsiniz, ancak check-in sırasında "proje standardı" olarak yeniden biçimlendirilir. Bence tek gerçek biçimlendirme standardı sekmeler yerine boşluk kullanmaktı.
TMN

1

Yuvalamayı azaltmanın yollarını önermeye yardımcı olacak Yeniden Biçimlendir'i kullanın. Ayrıca, bir fonksiyonun sadece bir şey yapması gerektiğini vurgulayan Bob Martin'in Temiz Kodu adlı kitabını okuyun ve bu nedenle her fonksiyon sadece yarım düzine satır uzunluğunda olmalıdır, bu yüzden endişelenecek çok fazla yuvalama seviyesine sahip olmayacaksınız.


1

Düzenleyiciye size yardımcı olabilecek bir eklenti var: C # Anahat .

Eklenti, iç içe kod bloklarını daraltmak, genişletmek ve vurgulamak için özellikler ekleyerek VS # için VS20xx düzenleyicisini genişletir. Bu özellikler, if, while vb. Gibi kod bloklarının iç içe geçmiş içeriklerinin daha kolay düzenlenmesine ve okunmasına olanak tanır.


0

Kodunuzu Visual Studio'da yazarsanız, oluşturduğunuz her yapının başı ile sonu arasında dikey noktaları gösteren bir eklenti de vardır.

Ama genel olarak "Kıvırcık Parantez Çorbası" na alışmanız biraz zaman alacak. (Btw, bu ifadeyi gerçekten çok seviyorum. Kulağa Big Bang Theory için Bölüm Adı gibi geliyor)


0

Girinti her iki sözdizimi stilinde nerede olduğunuzu söyler. Bir VB programı veya bir C # programını tek bir satıra yazarsanız, iç içe geçmiş sözdiziminin neresinde olduğunuzu söyleyemezsiniz. Makine, blok bitiş ifadelerini veya kıvırcık parantezleri ayrıştırır, ancak insanların girintiye ihtiyacı vardır.

Blok bitiş ifadeleri, programlama çok daha az etkileşimli ve görsel olduğunda delikli kartlar ve kağıt bant çağından gelir. Ya da, gerçekten, hiç etkileşimli değil. Programlara girmek zordu ve bu yüzden programcıların sözdizimi analizi ve hata kurtarma konusunda çok akıllı olmaları için derleyicilere ihtiyaçları vardı.

Geçtiğimiz dönemde, düzenleme-derleme-çalıştırma döngüsü kart deliciyle delikli kartlar hazırlamayı ve sonra da bir katilin delikli kartları alıp makineye göndermesini sağlayan bir iş gönderme penceresine dizilmiş olabilir. Daha sonra programcı çıktıyı (kağıda basılmış) başka bir pencereden toplar. Programda hatalar olsaydı, çıktı yalnızca derleyici tanılamasından oluşur. Geri dönüş süreleri uzun olduğunda, tanılama kalitesini artırmaya yardımcı olursa end if, sadece yerine yazmanın ek maliyeti )haklıdır, çünkü programcı, zaman kaybını azaltmak için tek bir yinelemede mümkün olduğunca çok hatayı düzeltmelidir. iş gönderme penceresinden tekrarlar.

Kapanmış kıvırcık küme ayracı eksik olduğunda, hangi açık küme ayrağının kapalı olmayan küme ayracı olduğunu söylemek zor. (Derleyici, eğitimli bir tahmin yapmak için girintiyi ayrıştırmak zorunda kalabilir.) Bir işlevin içindeki kapanış ayracı silerseniz, dosyanın geri kalanının tamamı bu işlevin bir parçası gibi görünür, bu da yardımcı olmayan hata iletilerinin telaşlanmasına neden olur. Bir end functionsözdiziminiz varsa , derleyici hatalı işlevin nerede bittiği sonucunu çıkarabilir, sonraki işlevleri düzgün bir şekilde çözümleyebilir ve ayrıştırabilir ve varsa anlamlı olan ek tanılamalar sağlayabilir.

Kodunuzu otomatik olarak girintilendiren ve renklendiren koda duyarlı metin düzenleyicide çalışırken, altmış veya daha fazla satır görebileceğiniz yüksek çözünürlüklü bir ekranda, bu tür beceriksiz diller için argümanlar artık geçerli değildir. Programları o kadar hızlı bir şekilde düzenleyebilir ve yeniden oluşturabilirsiniz, böylece her seferinde tek bir hatayla başa çıkabilirsiniz. Ayrıca, programın büyük bölümlerini aynı anda ekranda görüp uygun girintiyi koruyarak, bu tür yuvalama hatalarının oluşumunu ilk etapta azaltabilirsiniz. Ve iyi programlama metin editörü yazarken bazı sözdizimi hatalarını bile işaretleyecektir. Dahası, bir programın bloklarını sözdizimine göre çökertecek ve yapısının "taslağa benzeyen" bir görünümünü veren katlama editörleri var.

Lisp parantezleri en başından beri kullandı ve belki de tesadüfen değil, Lisp korsanları programlamayı küçük parçalarda (ifadeler) kabul eden sistemler oluşturarak etkileşimli bir deneyim olarak öncülük etti.

Aslında, Python dilinin gösterdiği gibi, bitiş sembollerine hiç ihtiyacınız yoktur. İdentation sadece edebilirsiniz olmak yapısı. İnsanlar, makinenin bitiş sembollerine veya ifadelerine dayandığı dillerde bile kod yapısını incelemek için zaten girintiyi kullanıyorlar.


-1

Bir IDE kullanıyorsanız, Crtl+ k+ düğmesine basmanız yeterlidir Dve IDE işin geri kalanını yapacaktır.


hangi IDE tutulması girinti için ctrl-shift-i ve biçimlendirme için ctrl-shift-f kullanır
cırcır ucube

görsel stüdyoda kontrol
Jagz W
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.