¿Por qué puedo crear una clase llamada "var"?

103

¿No es varuna palabra clave en C #? Pero, ¿por qué puedo hacer esto?

public class var { }

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

La varque se usa en el código es la varclase que se declara antes que la mainclase. Y el compilador ni siquiera se queja.

Mientras que cuando hago esto:

public class int { }

o esto:

public class true { }

El compilador dijo que into truees una palabra clave y no se puede usar así. ¿Por qué no es lo mismo con var?

Juan Isaías Carmona
fuente
6
¿Por qué querrías hacerlo? Tan confuso y difícil de leer.
duffymo
31
Var'y buena pregunta!
Richard
50
También puedes hacerlo var var = "var";en un método. Después de todo, es viernes.
Henk Holterman
11
Supongo que lo hicieron de esta manera para ser compatible con la creación de código antes de que "var" significara algo especial.
vidstige

Respuestas:

101

varno es una palabra clave según esta lista .

es una palabra clave contextual, por lo que, a partir del contexto, el compilador puede decidir cuál es su clase y cuál es la palabra clave contextual, y no surge ninguna confusión.

una palabra clave contextual es:

se usa para proporcionar un significado específico en el código, pero no es una palabra reservada en C #.

así que como no está reservado puedes usarlo.

Como se señaló en los comentarios anteriores, hay una discusión de las diferencias, así como una lista de las diversas palabras clave y palabras clave contextuales agregadas en cada versión de c # en el blog de Eric Lipperts.

Es interesante notar que desde que se decidió el conjunto de palabras clave en C # 1.0 no ha habido adiciones, para preservar la compatibilidad con versiones anteriores.

Sam Holder
fuente
1
Sin embargo, se clasifica en "Palabras clave de C #" aquí msdn.microsoft.com/en-us/library/bb383973.aspx ... ¡confuso!
Richard
4
Pero es un Contextual Keyword. "Una palabra clave contextual se utiliza para proporcionar un significado específico en el código, pero no es una palabra reservada en C # . Algunas palabras clave contextuales, como parcial y dónde, tienen significados especiales en dos o más contextos".
Tim Schmelter
5
@TimSchmelter Entonces "var" es una "palabra clave". No es una "palabra reservada", ¿verdad?
luiscubal
2
Supongo que es para mantener la compatibilidad con el código antiguo: si alguien tiene una clase nombrada var, no todo se rompe al actualizar C #.
Callum Rogers
1
@CallumRogers: es exactamente por eso que el equipo de C # hizo esto. Lo mismo para otras "palabras clave" introducidas posteriormente, como desde, unirse, etc. (todo contextual por cierto).
Abel
18

El compilador es lo suficientemente inteligente como para saber que el contexto que está utilizando varcomo nombre de clase nunca es un contexto para la palabra clave, por lo que lo permite (por lo que se define como una palabra clave contextual ).

Oded
fuente
Creo que esta respuesta es al menos algo engañosa. El compilador no es exactamente "lo suficientemente inteligente" para determinar si varse está utilizando como palabra clave en un código similar var testVar = new var();. Sí, el contexto, en términos de si varse definió un tipo personalizado con nombre , juega en él, pero es precisamente porque el compilador no es lo suficientemente inteligente en esos casos para saber si se var testVarrefiere a la clase varoa la palabra clave varque por defecto es la clase. en tal contexto. Si la varpalabra clave tuviera un nombre diferente, podría usarse en el mismo "contexto".
OR Mapper
Contraste eso con otras palabras clave contextuales, como add- aquí, el compilador sabe en cada caso si la palabra clave se refiere (declaración de evento; identificador no tendría ningún sentido allí), o si el código se refiere a un identificador (tipo o nombre en una declaración, uso del identificador dentro de un cuerpo de método; la palabra clave no tendría ningún sentido allí).
OR Mapper
12

Otra forma de ver esto: "var" como palabra clave no estaba en las primeras versiones de C # (a diferencia de "int" y "true"), por lo que es posible que haya escrito algún código que tenga una clase llamada "var". Esto estaba perfectamente bien y era legal. Luego, más tarde, cuando se agregó "var" al lenguaje, los diseñadores fueron tan amables que la convirtieron en una palabra clave solo en ciertos contextos, por lo que su clase var existente aún funcionaría.

Este es uno de los desafíos reales del diseño de lenguajes: cómo agregar nuevas funciones sin romper el código existente y sin hacer que las nuevas funciones sean engorrosas de usar.

Polyfun
fuente
8

En las versiones de C # anteriores a la versión 3, las variables locales tipadas implícitamente aún no eran compatibles, por lo que varno tenían un significado especial y era posible definir variables y clases nombradas var. Su programa de ejemplo es legal, porque ambas apariciones de varin se mainrefieren a la clase var.

C # 3 y versiones posteriores son compatibles con versiones anteriores, por lo que el código escrito en C # antes de la versión 3 aún se compila con los nuevos compiladores.

inty trueson palabras clave desde C # 1.

dtb
fuente
3

Las palabras clave se pueden reservar contextualmente. Cuando se analiza el código fuente, ese contexto se establece como parte del árbol de análisis. La evaluación de palabras clave tiene lugar dentro de ese contexto. Entonces, en este caso, var no está en un contexto reservado y no tendrá el mismo significado que cuando lo usa en una declaración de asignación. Creo que una de las razones de esta flexibilidad es que var se introdujo en C # 3, por lo que reservarlo en todas partes podría haber roto la compatibilidad con versiones anteriores en algunos programas, mientras que usarlo como una declaración de tipo de variable no se habría compilado en versiones anteriores, por lo que no hay rotura.

pfries
fuente