Pourquoi puis-je créer une classe nommée «var»?

103

N'est-ce pas varun mot-clé en C #? Mais pourquoi puis-je faire ça:

public class var { }

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

Le varqui est utilisé dans le code est la varclasse qui est déclarée avant la mainclasse. Et le compilateur ne se plaint même pas.

Pendant que je fais ça:

public class int { }

ou ca:

public class true { }

Le compilateur a dit que intou trueest un mot clé et ne peut pas être utilisé comme ça. Pourquoi n'en est-il pas de même var?

John Isaiah Carmona
la source
6
Pourquoi voudriez-vous? Si déroutant et difficile à lire.
duffymo
31
var'y bonne question!
Richard
50
Vous pouvez également le faire var var = "var";dans une méthode. Après tout, c'est vendredi.
Henk Holterman
11
Je suppose qu'ils l'ont fait de cette façon pour être rétrocompatible avec le code create avant que "var" ne signifiait quelque chose de spécial.
vidstige

Réponses:

101

varn'est pas un mot-clé selon cette liste .

c'est un mot clé contextuel, donc à partir du contexte, le compilateur est capable de décider quelle est votre classe et quel est le mot clé contextuel, et aucune confusion ne survient.

un mot-clé contextuel est:

utilisé pour fournir une signification spécifique dans le code, mais ce n'est pas un mot réservé en C #.

comme il n'est pas réservé, vous pouvez l'utiliser.

Comme indiqué dans les commentaires ci-dessus, il y a une discussion des différences ainsi qu'une liste des différents mots-clés et mots-clés contextuels ajoutés à chaque version de c # sur le blog d'Eric Lipperts

Il est intéressant de noter que depuis que l'ensemble des mots-clés a été décidé en C # 1.0, il n'y a pas eu d'ajouts, afin de préserver la compatibilité ascendante.

Sam Holder
la source
1
Cependant, il est classé sous "Mots clés C #" ici msdn.microsoft.com/en-us/library/bb383973.aspx ... déroutant!
Richard
4
Mais c'est un Contextual Keyword. "Un mot clé contextuel est utilisé pour fournir une signification spécifique dans le code, mais ce n'est pas un mot réservé en C # . Certains mots clés contextuels, tels que partial et where, ont une signification particulière dans deux contextes ou plus."
Tim Schmelter
5
@TimSchmelter Alors "var" est un "mot-clé". Pas un "mot réservé", non?
luiscubal
2
Je suppose que c'est pour maintenir la compatibilité avec l'ancien code - si quelqu'un avait une classe nommée, vartout ne se cassait pas lors de la mise à niveau de C #.
Callum Rogers
1
@CallumRogers: c'est exactement pourquoi l'équipe C # a fait cela. Idem pour les autres "mots-clés" introduits plus tard comme from, join etc (tous contextuels d'ailleurs).
Abel
18

Le compilateur est suffisamment intelligent pour savoir que le contexte que vous utilisez varcomme nom de classe n'est jamais un contexte pour le mot-clé, donc le permet (c'est pourquoi il est défini comme un mot-clé contextuel ).

Oded
la source
Je pense que cette réponse est au moins quelque peu trompeuse. Le compilateur n'est pas exactement "assez intelligent" pour déterminer s'il varest utilisé comme mot clé dans du code comme var testVar = new var();. Oui, le contexte, en termes de savoir si un type personnalisé nommé a varété défini, joue dedans, mais c'est précisément parce que le compilateur n'est pas assez intelligent dans ces cas pour savoir s'il var testVarfait référence à la classe varou au mot var- clé qu'il par défaut à la classe dans un tel contexte. Si le varmot - clé était nommé différemment, il pourrait être utilisé dans le même «contexte».
OR Mapper
Comparez cela avec d'autres mots-clés contextuels, tels que add- ici, le compilateur sait en effet à chaque occurrence si le mot-clé est destiné (déclaration d'événement; identifiant n'aurait aucun sens là-bas), ou si le code fait référence à un identifiant (type ou nom dans une déclaration, utilisation de l'identifiant dans le corps d'une méthode; le mot clé n'aurait aucun sens ici)
OR Mapper
12

Une autre façon de voir ceci: "var" en tant que mot clé n'était pas dans les premières versions de C # (contrairement à "int" et "true"), vous avez donc peut-être écrit du code qui avait une classe appelée "var". C'était parfaitement bien et légal. Puis plus tard, lorsque "var" a été ajouté au langage, les concepteurs ont eu la gentillesse d'en faire un mot-clé uniquement dans certains contextes, de sorte que votre classe var existante fonctionnerait toujours.

C'est l'un des vrais défis de la conception de langage - comment ajouter de nouvelles fonctionnalités sans casser le code existant et sans rendre les nouvelles fonctionnalités fastidieuses à utiliser.

Polyfun
la source
8

Dans les versions C # antérieures à la version 3, les variables locales typées implicitement n'étaient pas encore prises en charge, elles varn'avaient donc aucune signification particulière et il était possible de définir des variables et des classes nommées var. Votre exemple de programme est légal, car les deux occurrences de varin font mainréférence à la classe var.

C # 3 et les versions ultérieures sont compatibles vers le bas, donc le code écrit en C # avant la version 3 se compile toujours avec les nouveaux compilateurs.

intet truesont des mots-clés depuis C # 1.

dtb
la source
3

Les mots clés peuvent être réservés de manière contextuelle. Lorsque le code source est analysé, ce contexte est établi dans le cadre de l'arborescence d'analyse. L'évaluation des mots-clés a lieu dans ce contexte. Donc, dans ce cas, var n'est pas dans un contexte réservé et n'aura pas la même signification que lorsque vous l'utilisez dans une instruction d'affectation. Je pense qu'une des raisons de cette flexibilité est que var a été introduit dans C # 3, donc le rendre réservé partout pourrait avoir rompu la compatibilité descendante dans certains programmes, alors que l'utiliser comme une déclaration de type variable n'aurait pas été compilé dans les versions précédentes, il n'y a donc pas rupture.

frites
la source