Perché posso creare una classe denominata "var"?


103

Non è varuna parola chiave in C #? Ma perché posso farlo:

public class var { }

public class main
{
    public static void main(string[] args)
    {
        var testVar = new var();
    }
}

Quella varutilizzata nel codice è la varclasse dichiarata prima della mainclasse. E il compilatore non si lamenta nemmeno.

Mentre quando lo faccio:

public class int { }

o questo:

public class true { }

Il compilatore ha detto che into trueè una parola chiave e non può essere utilizzata in questo modo. Perché non è lo stesso con var?


6
Perché dovresti volerlo? Così confuso e difficile da leggere.
duffymo


31
buona domanda!
Richard

50
Puoi anche farlo var var = "var";in un metodo. Dopotutto, è venerdì.
Henk Holterman

11
Immagino che abbiano fatto in questo modo per essere retrocompatibili con il codice creato prima che "var" significasse qualcosa di speciale.
vidstige

Risposte:


101

varnon è una parola chiave secondo questo elenco .

è una parola chiave contestuale, quindi dal contesto il compilatore è in grado di decidere quale è la tua classe e quale è la parola chiave contestuale, e non sorge alcuna confusione.

una parola chiave contestuale è:

utilizzato per fornire un significato specifico nel codice, ma non è una parola riservata in C #.

quindi poiché non è riservato puoi usarlo.

Come sottolineato nei commenti sopra, c'è una discussione sulle differenze, nonché un elenco delle varie parole chiave e parole chiave contestuali aggiunte a ciascuna versione di c # sul blog di Eric Lipperts

È interessante notare che da quando il set di parole chiave è stato deciso in C # 1.0 non sono state aggiunte aggiunte, in modo da preservare la retrocompatibilità.


1
Tuttavia è classificato in "Parole chiave C #" qui msdn.microsoft.com/en-us/library/bb383973.aspx ... confuso!
Richard

4
Ma è un file Contextual Keyword. "Una parola chiave contestuale viene utilizzata per fornire un significato specifico nel codice, ma non è una parola riservata in C # . Alcune parole chiave contestuali, come partial e where, hanno significati speciali in due o più contesti."
Tim Schmelter

5
@TimSchmelter Allora "var" è una "parola chiave". Non solo una "parola riservata", giusto?
luiscubal

2
Immagino che sia per mantenere la compatibilità con il vecchio codice: se qualcuno aveva una classe denominata, varnon tutto si interrompe durante l'aggiornamento C #.
Callum Rogers

1
@CallumRogers: questo è esattamente il motivo per cui il team di C # lo ha fatto. Lo stesso per altre "parole chiave" introdotte successivamente come from, join ecc (tutte contestuali tra l'altro).
Abel

18

Il compilatore è abbastanza intelligente da sapere che il contesto che stai usando varcome nome di classe non è mai un contesto per la parola chiave, quindi lo consente (motivo per cui è definita come parola chiave contestuale ).


Penso che questa risposta sia almeno in qualche modo fuorviante. Il compilatore non è esattamente "abbastanza intelligente" per determinare se varviene utilizzato come parola chiave in codice simile var testVar = new var();. Sì, il contesto, in termini di vardefinizione di un tipo personalizzato denominato , gioca in esso, ma è proprio perché il compilatore non è abbastanza intelligente in quei casi da sapere se si var testVarriferisce alla classe varo alla parola chiave varche di default è la classe in un tale contesto. Se la varparola chiave fosse denominata in modo diverso, potrebbe essere utilizzata nello stesso "contesto".
OR Mapper

Confrontalo con altre parole chiave contestuali, come add- qui, il compilatore sa in ogni caso se la parola chiave è intesa (dichiarazione di evento; l'identificatore non avrebbe alcun senso lì), o se il codice si riferisce a un identificatore (tipo o nome in una dichiarazione, uso dell'identificatore all'interno del corpo di un metodo; la parola chiave non avrebbe alcun senso lì).
OPPURE Mapper

12

Un altro modo di vedere questo: "var" come parola chiave non era nelle prime versioni di C # (a differenza di "int" e "true"), quindi potresti aver scritto del codice che aveva una classe chiamata "var". Questo andava benissimo e legale. Successivamente, quando "var" è stato aggiunto al linguaggio, i progettisti sono stati così gentili da renderla una parola chiave solo in determinati contesti, quindi la tua classe var esistente avrebbe comunque funzionato.

Questa è una delle vere sfide della progettazione del linguaggio: come aggiungere nuove funzionalità senza rompere il codice esistente e senza rendere le nuove funzionalità scomode da usare.


8

Nelle versioni C # precedenti alla 3, le variabili locali tipizzate in modo implicito non erano ancora supportate, quindi varnon avevano alcun significato speciale ed era possibile definire variabili e classi denominate var. Il tuo programma di esempio è legale, perché entrambe le occorrenze di varin si mainriferiscono alla classe var.

C # 3 e le versioni successive sono compatibili con le versioni precedenti, quindi il codice scritto in C # prima della versione 3 viene comunque compilato con i nuovi compilatori.

inte truesono parole chiave dal C # 1.


3

Le parole chiave possono essere riservate contestualmente. Quando il codice sorgente viene analizzato, quel contesto viene stabilito come parte dell'albero di analisi. La valutazione delle parole chiave avviene all'interno di quel contesto. Quindi, in questo caso, var non è in un contesto riservato e non avrà lo stesso significato di quando lo si utilizza in un'istruzione di assegnazione. Credo che uno dei motivi di questa flessibilità sia che var è stato introdotto in C # 3, quindi renderlo riservato ovunque potrebbe aver rotto la compatibilità con le versioni precedenti in alcuni programmi, mentre usarlo come dichiarazione di tipo variabile non sarebbe stato compilato nelle versioni precedenti, quindi non c'è rottura.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.