2010-08-17 11 views
37

stavo navigando un colleghi codice C# oggi e hanno trovato la seguente:L'istruzione using C# può essere scritta senza le parentesi graffe?

using (MemoryStream data1 = new MemoryStream()) 
    using (MemoryStream data2 = new MemoryStream()) 
    { 
     // Lots of code.......... 
    } 

avevo sempre visto la dichiarazione using seguita da una coppia di parentesi graffe che ha definito l'ambito della vita dell'oggetto. Il mio collega che ha scritto il codice ha detto che le parentesi graffe per la dichiarazione data1using non erano necessarie e il codice ha fatto la stessa cosa come se fossero presenti e annidato la dichiarazione data2using. Quindi, cosa succede quando le parentesi graffe sono ommitted?

+1

Solo i miei 2 centesimi - Mentre è "possibile" fare questo, come dimostrano le risposte, io sono del parere che non si dovrebbe fare, per scopi di leggibilità. Per me, è come avvolgere il se/else/while/lock/etc. blocchi in parentesi graffe - anche se non sono necessari, è molto più facile da leggere. –

+9

A mio parere, le istruzioni 'using' impilate, come sopra, sono ** molto ** più leggibili delle istruzioni' using' nidificate. Soprattutto nei casi in cui si stanno concatenando 3-4 stream/StreamReader per eseguire una singola serie di operazioni. –

+2

@Joel: Forse come qualsiasi altra cosa, la situazione specifica dovrebbe essere presa in considerazione.Se erano solo due, la mia opinione è assolutamente nidificarle con bretelle. Se parliamo di 4 come dici tu, forse è l'approccio migliore. Ma la prima volta che devi accedere a data1 prima della creazione di data2, significa cambiare la leggibilità del codice anziché aggiungere semplicemente una riga di codice. –

risposta

95

Sì, si può anche metterli in una utilizzando dichiarazione:

using (MemoryStream data1 = new MemoryStream(), 
        data2 = new MemoryStream()) 
{ 
    // do stuff 
} 
+27

+1. Non sapevo che potessi fare questo – fletcher

+0

+1 Bello, l'avevo già visto prima ... ma me ne sono dimenticato. –

+0

Sono abbastanza sicuro che il comportamento di questo costrutto sia diverso in alcuni casi. Non ricordo esattamente perché adesso, ma credo di averlo letto in uno dei libri di Bill Wagners. – fearofawhackplanet

18

Le stesse regole si applicano quando si omettono le parentesi graffe in un'istruzione for o if.

Per inciso se si riflette nel codice compilato, il compilatore del compilatore aggiunge le parentesi.

+2

Una differenza è che, quando si annidano le istruzioni 'for', si indenta quello interno, ma le istruzioni' using' nidificate sono di solito allineate a sinistra. Questa è una questione di convenzione comune, non di sintassi del linguaggio, ovviamente. –

+7

+1, nitpick point: il compilatore non aggiunge effettivamente parentesi, il decompilatore li inserisce. – JaredPar

+0

@JaredPar Grazie per il chiarimento. Non lo sapevo. –

3

Esattamente quello che ha detto il tuo collega, è l'equivalente di annidare le affermazioni. Lo smaltimento di data2 verrebbe chiamato immediatamente prima della funzione di eliminazione per data1.

1

Se c'è solo un'istruzione che segue l'istruzione, le bracette non sono necessarie. È come con la dichiarazione if.

if(true) 
{ 
    Console.Writeline("hello") 
} 

significa la stessa che

if(true) 
    Console.Writeline("hello") 
15

Esattamente quello che ha detto. Il codice di cui sopra è esattamente lo stesso di scrittura:

using (MemoryStream data1 = new MemoryStream()) 
{ 
    using (MemoryStream data2 = new MemoryStream()) 
    { 
     // Lots of code 
    } 
} 

è possibile omettere le parentesi graffe dopo un if/else/per/durante/usare/etc dichiarazione fino a quando v'è un solo comando all'interno della dichiarazione. Esempi:

// Equivalent! 
if (x==6) 
    str = "x is 6"; 

if(x == 6) { 
    str = "x is 6"; 
} 

// Equivalent! 
for (int x = 0; x < 10; ++x) z.doStuff(); 

for (int x = 0; x < 10; ++x) { 
    z.doStuff(); 
} 

// NOT Equivalent! (The first one ONLY wraps the p = "bob";!) 
if (x == 5) 
p = "bob"; 
z.doStuff(); 

if (x == 5) { 
    p = "bob"; 
    z.doStuff(); 
} 
+1

Davvero una buona idea pubblicare esempi come questi @Stephen! – Cyberherbalist

3

Questo è fattibile ma rischioso, perché se qualcuno decide in seguito che vogliono fare qualcosa per dati1 prima di altre cose accada ad esso, potrebbero posizionarlo subito dopo l'utilizzo di data1, che lo porterebbe fuori dall'ambito di applicazione di data2. Questo probabilmente interromperà la compilazione, ma è comunque una scorciatoia sintattica rischiosa e inutile.

+8

Quella persona dovrebbe probabilmente considerare una diversa linea di lavoro. – spoulson

+1

@spoulson: vero per molte persone che non lo fanno, ma è ancora nostro compito mantenere il codice come mantenibile dagli altri il più possibile, per timore che altri mettano bug nel nostro codice .. –

0

Come si è detto: dato che solo una riga dopo una dichiarazione funzionerà senza le parentesi graffe. Tuttavia, le persone stanno trascurando di mostrare nei loro esempi che quella linea può essere un if/use/for con le proprie parentesi graffe. Ecco un esempio:

if(foo) 
    if(bar) 
    { 
    doStuff(); 
    } 
Problemi correlati