Trattare con zuppa brace riccia

11

Ho programmato sia in C # che in VB.NET per anni, ma principalmente in VB. Sto facendo uno spostamento di carriera verso C # e, nel complesso, mi piace C # meglio.

Un problema che sto avendo, però, è la zuppa di brace riccia. In VB, ogni parola chiave struttura ha una parola chiave close corrispondente, ad esempio:

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

Lo stesso codice scritto in C # finisce per essere molto difficile da leggere:

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

Essendo abituato a VB, mi chiedo se ci sia una tecnica impiegata dai programmatori in stile c per migliorare la leggibilità e per garantire che il tuo codice finisca nel "blocco" corretto. L'esempio sopra è relativamente facile da leggere, ma a volte alla fine di un pezzo di codice avrò 8 o più livelli di parentesi graffe, richiedendomi di scorrere più pagine per capire quale coppia termina il blocco che mi interessa a.

    
posta JDB 07.11.2012 - 16:38
fonte

13 risposte

38

Metti la parentesi graffa iniziale nello stesso "rank" di quello finale, in questo modo:

namespace ... 
{
    class ... 
    {
        function ... 
        {
            for ... 
            {
                using ... 
                {
                    if ... 
                    {
                        ...
                    }
                    if ... 
                    {
                        ...
                    }
                }
            }
            // It's the 'function' level!
        }
    }
}
    
risposta data 07.11.2012 - 16:41
fonte
14
  • A seconda dell'IDE: metti il cursore sulla parentesi aperta / chiusa e verrà evidenziato sia quello che la parentesi corrispondente.
  • Comprimi il blocco e mostra dove si apre / si chiude.
  • Scrivi blocchi di codice più piccoli. Sul serio. Controlla Clean Code e non riesci più a eseguire questo problema (e disponi di un codice più leggibile / gestibile).

Una nota, la seguente sintassi c # valida potrebbe aiutare la tua situazione particolare:

using (var type = new MyDisposable1())
using (var type2 = new MyDisposable2())
{
    /* do what you will with type2 and type2 */
}
    
risposta data 07.11.2012 - 16:45
fonte
5

Una convenzione comune è aggiungere un commento dopo la parentesi di chiusura per indicare la struttura che sta chiudendo:

if {
   ...
} // end if

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

ecc. Non mi sono mai interessato a questa convention da solo, ma alcune persone lo trovano utile.

    
risposta data 07.11.2012 - 16:42
fonte
5

In generale, quando diventa difficile abbinare le parentesi in qualsiasi stile, probabilmente significa che il metodo è troppo lungo e deve essere rielaborato.

    
risposta data 07.11.2012 - 21:36
fonte
5

Penso che tu abbia bisogno di resistere con le parentesi graffe. Alla fine diventeranno una seconda natura per te e ti starai chiedendo come mai hai vissuto senza di loro.

Assicurati che siano indentati in modo appropriato e che venga seguita una convenzione di spaziatura (non importa quale).

    
risposta data 07.11.2012 - 16:51
fonte
4

Rimuovo 2 livelli di nidificazione comprimendo orizzontalmente lo spazio dei nomi e gli ambiti delle classi. Si noti che i metodi sono a filo con il bordo sinistro dello schermo. Non vedo il punto di perdere 2 livelli di indentazione in ogni file.

Dopo questo è raro che tu abbia mai nidificato a più di 4 livelli di profondità.

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
    
risposta data 07.11.2012 - 22:58
fonte
1

Recentemente ho deciso di provare e formalizzare due regole sui costrutti del controllo di flusso che fondamentalmente si comportano in questo modo:

  • Non dovresti avere nient'altro che necessari costrutti del flusso di codice
  • Dovresti rendere i costrutti del flusso di codice quanto più piccoli possibile

Per le ragioni esatte che hai menzionato e di cui sono chiaramente al corrente, penso che queste siano delle ottime regole da seguire. Ci sono un paio di semplici tecniche che puoi impiegare per realizzarle:

  • Chiudi l'ambito il più presto possibile (questo include l'ambito dei cicli e delle funzioni)
  • Guarda per gli els che potrebbero essere mitigati uscendo dalla funzione precedente e applicando la tecnica dell'ambito di uscita come ho detto
  • Inverti i controlli condizionali quando il codice all'interno di if è eccezionale rispetto a
  • Codice fattoriale all'interno di un loop out su un altro metodo quando la dimensione del loop aumenta per oscurare il resto del metodo
  • Guarda tutti gli ambiti che contengono solo un altro ambito, ad esempio una funzione il cui intero ambito è riempito da un if con niente al di fuori del if

Ho dettagliato qui esempi di in che modo non seguirli può finire con te come hai detto e mettere il codice nel blocco di codice sbagliato, che è cattivo e una facile causa di bug che si verificano durante la manutenzione.

    
risposta data 07.11.2012 - 16:50
fonte
1

Questa è una delle più antiche cause di guerra nel campo dell'informatica, purtroppo. Argomenti ragionevoli possono essere formulati da entrambe le parti (migliore economia immobiliare verticale rispetto a una più semplice capacità di abbinare visivamente il tutore di apertura con la parentesi di chiusura), ma in realtà un semplice formattatore di codice sorgente risolverà tutto per te. MS Visual C # ne ha uno integrato che funziona bene.

Siate comunque consapevoli che se lavorate come parte di una squadra ci si aspetta che si conformino alle convenzioni utilizzate da quella squadra, quindi è utile acquisire familiarità con entrambi gli stili e astenersi dall'ottenere stili religiosi più coraggiosi.

Quindi, mentre stai imparando a tutti i costi, concentrati sullo stile che ti rende più facile imparare, ma tieni d'occhio l'altro mentre ci sei e andrai bene.

    
risposta data 07.11.2012 - 17:01
fonte
1

Usa il programma di richiamo, che ti aiuterà a consigliare modi per ridurre il nidificazione. Inoltre, leggi il libro di Bob Martin Pulisci codice , che sottolinea che una funzione dovrebbe fare solo una cosa, e quindi ogni funzione dovrebbe essere lunga solo una mezza dozzina di righe, quindi non avrai molti livelli di nidificazione di cui preoccuparsi.

    
risposta data 08.11.2012 - 02:59
fonte
1

C'è un componente aggiuntivo nell'editor che può aiutarti a: C # Outline .

Il componente aggiuntivo estende l'editor VS20xx per C # aggiungendo funzionalità per comprimere, espandere ed evidenziare blocchi di codice annidati. Queste funzionalità consentono di semplificare la modifica e la lettura di contenuti nidificati di blocchi di codice come if, while, ecc.

    
risposta data 07.11.2012 - 17:20
fonte
0

Se scrivi il tuo codice in Visual Studio, c'è anche un plugin che mostra i punti verticali tra l'inizio e la fine di ogni struttura che tu costruisci.

Ma nel complesso penso che ci vorrà un po 'di tempo prima che tu sia abituato a "Ricci-Brace-Zuppa". (A proposito, mi piace molto quell'espressione, un po 'come un Episode-Name per The Big Bang Theory)

    
risposta data 07.11.2012 - 20:53
fonte
0

L'indentazione ti dice dove sei, in entrambi gli stili di sintassi. Se scrivi un programma VB o un programma C # su una sola riga, presto non sarai in grado di dire dove sei nella sintassi annidata. La macchina analizza le frasi di fine blocco o le parentesi graffe, ma gli umani hanno bisogno di indentazione.

Le frasi finali bloccate derivano da un'era di schede perforate e nastro di carta, quando la programmazione era molto meno interattiva e visiva. O, davvero, non interattivo. È stato difficile inserire programmi, quindi i programmatori avevano bisogno di compilatori per essere molto intelligenti nell'analisi della sintassi e nel ripristino degli errori.

In quell'era passata, il ciclo di compilazione di compilazione potrebbe aver comportato la preparazione di schede perforate con un perforatore di schede, e poi il lining fino alla finestra di presentazione del lavoro in cui un impiegato prendeva le schede perforate e le inviava alla macchina. Successivamente, il programmatore avrebbe raccolto l'output (stampato su carta) da un'altra finestra. Se il programma avesse errori, l'output consisterebbe solo nella diagnostica del compilatore. Quando i tempi di risposta sono lunghi, il costo aggiuntivo di digitare end if anziché solo ) è giustificato se aiuta a migliorare la qualità della diagnostica, poiché il programmatore deve correggere il maggior numero possibile di errori in una singola iterazione per ridurre il numero di iterazioni che perdono tempo attraverso la finestra di invio del lavoro.

Quando manca una parentesi graffa di chiusura, è difficile dire quale controvento sia quella che non è chiusa. (Il compilatore potrebbe dover analizzare il rientro per fare un'ipotesi plausibile). Se elimini una parentesi chiusa all'interno di una funzione, sembra che l'intero resto del file sia parte di quella funzione, risultando in una raffica di messaggi di errore inutili. Mentre se si ha una sintassi di end function , il compilatore può dedurre dove finisce la funzione errata, recuperare e analizzare correttamente le funzioni successive, fornendo ulteriori strumenti diagnostici, se ce ne sono, che sono significativi.

Quando lavori in un editor di testo in grado di riconoscere il codice che indentifica e colorizza automaticamente il tuo codice, su una schermata ad alta risoluzione in cui è possibile visualizzare sessanta o più righe, gli argomenti per quei tipi di linguaggi maldestri non si applicano più. È possibile modificare e ricostruire i programmi in modo incrementale in modo così rapido da poter gestire un errore alla volta. Inoltre, visualizzando contemporaneamente ampie sezioni del programma sullo schermo e mantenendo il corretto rientro, è possibile ridurre l'occorrenza di tali tipi di errori di annidamento. E un buon editor di testo di programmazione segnalerà anche alcuni tipi di errori di sintassi durante la digitazione. Inoltre, esistono editor pieghevoli che comprimono i blocchi di un programma in base alla sua sintassi, fornendo una vista "a tratteggio" della sua struttura.

Lisp ha usato le parentesi dall'inizio e forse, non a caso, gli hacker Lisp hanno aperto la strada alla programmazione come un'esperienza interattiva costruendo sistemi che accettavano programmi in piccoli blocchi (espressioni).

In realtà, non hai bisogno di simboli finali, come illustra il linguaggio Python. L'identificazione può solo essere la struttura. Gli umani usano già indentazione per ingannare la struttura del codice anche nelle lingue in cui la macchina si basa su simboli o frasi finali.

    
risposta data 08.11.2012 - 01:18
fonte
-1

Se stai usando un IDE, basta premere Crtl + k + D e l'IDE farà il resto del lavoro.

    
risposta data 08.11.2012 - 10:50
fonte

Leggi altre domande sui tag