Por que posso criar uma classe chamada “var”?

103

Não é varuma palavra-chave em C #? Mas por que posso fazer isso:

public class var { }

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

O varque é usado no código é a varclasse que é declarada antes da mainclasse. E o compilador nem reclama.

Enquanto eu faço isso:

public class int { }

ou isto:

public class true { }

O compilador disse que intou trueé uma palavra-chave e não pode ser usada dessa forma. Por que não é o mesmo com var?

John Isaiah Carmona
fonte
6
Por que você iria querer? Tão confuso e difícil de ler.
duffymo
31
var'y boa pergunta!
Richard
50
Você também pode fazer var var = "var";em um método. Afinal, é sexta-feira.
Henk Holterman
11
Estou supondo que eles fizeram isso dessa forma para ser compatível com o código criado antes que "var" significasse algo especial.
vidstige

Respostas:

101

varnão é uma palavra-chave de acordo com esta lista .

é uma palavra-chave contextual, portanto, a partir do contexto, o compilador é capaz de decidir qual é a sua classe e qual é a palavra-chave contextual, e nenhuma confusão surge.

uma palavra-chave contextual é:

usado para fornecer um significado específico no código, mas não é uma palavra reservada em C #.

então, como não está reservado, você pode usá-lo.

Conforme apontado nos comentários acima, há uma discussão sobre as diferenças, bem como uma lista das várias palavras-chave e palavras-chave contextuais adicionadas a cada versão de c # no blog de Eric Lipperts

É interessante notar que, uma vez que o conjunto de palavras-chave foi decidido em C # 1.0, não houve adições, de modo a preservar a compatibilidade com versões anteriores.

Sam Holder
fonte
1
No entanto, é categorizado em "Palavras-chave C #" aqui msdn.microsoft.com/en-us/library/bb383973.aspx ... confuso!
Richard
4
Mas é um Contextual Keyword. "Uma palavra-chave contextual é usada para fornecer um significado específico no código, mas não é uma palavra reservada em C # . Algumas palavras-chave contextuais, como parcial e onde, têm significados especiais em dois ou mais contextos."
Tim Schmelter
5
@TimSchmelter Então "var" é uma "palavra-chave". Só não uma "palavra reservada", certo?
luiscubal
2
Acho que é para manter a compatibilidade com o código antigo - se alguém tivesse uma classe chamada var, nem tudo quebra ao atualizar o C #.
Callum Rogers
1
@CallumRogers: é exatamente por isso que a equipe C # fez isso. O mesmo para outras "palavras-chave" introduzidas posteriormente como from, join etc (todas contextuais, a propósito).
Abel de
18

O compilador é inteligente o suficiente para saber que o contexto que você está usando varcomo nome de classe nunca é um contexto para a palavra-chave, portanto, permite isso (é por isso que é definido como uma palavra-chave contextual ).

Oded
fonte
Acho que essa resposta é pelo menos um pouco enganosa. O compilador não é exatamente "inteligente o suficiente" para determinar se varestá sendo usado como uma palavra-chave em código como var testVar = new var();. Sim, o contexto, em termos de se um tipo personalizado chamado varfoi definido, joga nele, mas é precisamente porque o compilador não é inteligente o suficiente nesses casos para saber se se var testVarrefere à classe varou à palavra var- chave que o padrão para a classe em tal contexto. Se a varpalavra - chave tivesse um nome diferente, ela poderia ser usada no mesmo "contexto".
OR Mapper
Compare isso com outras palavras-chave contextuais, como add- aqui, o compilador realmente sabe em cada ocorrência se a palavra-chave se refere a (declaração de evento; identificador não faria nenhum sentido lá), ou se o código está se referindo a um identificador (tipo ou nome em uma declaração, uso do identificador dentro de um corpo de método; a palavra-chave não faria sentido aqui).
OR Mapper
12

Outra maneira de ver isso: "var" como palavra-chave não estava nas primeiras versões do C # (ao contrário de "int" e "true"), então você pode ter escrito algum código que tinha uma classe chamada "var". Isso estava perfeitamente bem e legal. Mais tarde, quando "var" foi adicionado à linguagem, os designers foram gentis em torná-la uma palavra-chave apenas em determinados contextos, de forma que sua classe var existente ainda funcionasse.

Este é um dos desafios reais do design de linguagem - como adicionar novos recursos sem quebrar o código existente e sem tornar os novos recursos difíceis de usar.

Polyfun
fonte
8

Nas versões C # anteriores à versão 3, as variáveis ​​locais digitadas implicitamente ainda não eram suportadas, portanto var, não tinham significado especial e era possível definir variáveis ​​e classes nomeadas var. Seu programa de exemplo é legal, porque ambas as ocorrências de varna mainreferida classe var.

C # 3 e versões posteriores são compatíveis com versões anteriores, portanto, o código escrito em C # antes da versão 3 ainda é compilado com os novos compiladores.

inte truesão palavras-chave desde C # 1.

dtb
fonte
3

Palavras-chave podem ser reservadas contextualmente. Quando o código-fonte é analisado, esse contexto é estabelecido como parte da árvore de análise. A avaliação das palavras-chave ocorre dentro desse contexto. Portanto, neste caso, var não está em um contexto reservado e não terá o mesmo significado de quando você o usa em uma instrução de atribuição. Eu acredito que uma razão para essa flexibilidade é que var foi introduzido em C # 3, então torná-lo reservado em todos os lugares pode ter quebrado a compatibilidade com versões anteriores em alguns programas, enquanto usá-lo como uma declaração de tipo variável não teria sido compilado em versões anteriores, então não há quebra.

pfries
fonte