2010-03-02 11 views
9

Domanda sciocca, ma perché la seguente riga viene compilata?Perché questo snippet C# è legale?

int[] i = new int[] {1,}; 

Come potete vedere, non ho inserito il secondo elemento e lasciato una virgola lì. Ancora compila anche se ti aspetteresti che non lo fosse.

+4

http://stackoverflow.com/questions/2311864/history-of-trailing-comma-in-programming-language-grammars –

+0

Sono stupito chiunque sarebbe soddisfatto della risposta "Perché è quello che dice la specifica". Le risposte di Steck e Jimmy spiegano * perché è vantaggioso *. –

+0

Ho votato perché sono stato colpito dalla freccia .... – Jimmy

risposta

11

suppongo perché lo standard ECMA 334 dire:

array-initializer: 
    { variable-initializer-list(opt) } 
    { variable-initializer-list , } 
variable-initializer-list: 
    variable-initializer 
    variable-initializer-list , variable-initializer 
variable-initializer: 
    expression 
    array-initializer 

Come si può vedere, la virgola finale è consentito:

{ variable-initializer-list , } 
          ↑ 

P.S. per una buona risposta (anche se questo fatto è stato già indicato da molti utenti). :)

La virgola finale può essere utilizzata per semplificare l'implementazione di generatori di codice automatici (i generatori possono evitare di verificare l'ultimo elemento nell'inizializzatore, poiché dovrebbe essere scritto senza la virgola finale) e l'inizializzazione dell'array condizionale con le direttive del preprocessore.

7

Dovrebbe essere compilato per definizione.

Non c'è un secondo elemento. Una virgola finale è una sintassi valida quando si definisce una raccolta di elementi.

i è un array di int contenente un singolo elemento, i[0] contenente il valore 1.

+0

Quella virgola extra mi dice che è previsto un altro valore. –

+7

Questa potrebbe essere la tua interpretazione, ma non è così che viene definita. –

+0

Potrebbe essere il caso, ma non ha ancora alcun senso a prescindere dalle specifiche. –

5

è quindi è possibile farlo e copiare/incollare le linee intorno senza preoccuparsi di eliminare/aggiungere le virgole nei luoghi corretti.

int[] i = new[] { 
    someValue(), 
    someOtherValue(), 
    someOtherOtherValue(), 

    // copy-pasted zomg! the commas don't hurt! 
    someValue(), 
    someOtherValue(), 
    someOtherOtherValue(), 

}; 
+0

Secondo un post simile a quello jleedevpointed out, per rendere più facile la generazione automatica del codice. Mi ha appena catturato supprise tutto questo :-) –

10

Questo è lo zucchero di sintassi. In particolare, tale registrazione può essere utile nella generazione del codice.

int[] i = new int[] { 
    1, 
    2, 
    3, 
}; 

Inoltre, quando si scrive in questo modo, per aggiungere una nuova riga è necessario aggiungere il testo solo in una riga.

+1

Fastidioso che questo sia permesso negli array, ma non in Enum, dove sarebbero molto più utili. –

+3

è consentito in enum (appena provato in C# 3.0) –

+0

IMO, questa e la risposta di Jimmy devono essere modificate insieme e quindi il risultato accettato! E aggiungerei l'osservazione che questo è il modo in cui ';' funziona tra le affermazioni, esattamente per la stessa ragione. E quello in Erlang, dove il simbolo finale è diverso (un punto invece di una virgola), all'inizio può sembrare confortante simile all'inglese, ma gli utenti finiscono per odiarlo per gli stessi motivi qui riportati. –

7

Un altro vantaggio di consentire una virgola finale è in associazione con le direttive del preprocessore:

int[] i = new[] { 
#if INCLUDE1 
    1, 
#endif 

#if INCLUDE2 
    2, 
#endif 

#if INCLUDE3 
    3, 
#endif 
}; 

Senza permettendo una virgola finale, che sarebbe molto più difficile da scrivere.

3

Lo stesso vale per le enumerazioni:

enum Foo 
{ 
    Bar, 
    Baz, 
}; 
Problemi correlati