103

Isn't var a keyword in C#? But why can I do this:

public class var { }

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

The var that is used in the code is the var class that is declared before the main class. And the compiler doesn't even complain.

While when I do this:

public class int { }

or this:

public class true { }

The compiler said that int or true is a keyword and cannot be used like that. Why is it not the same with var?

svick
  • 236,525
  • 50
  • 385
  • 514
John Isaiah Carmona
  • 5,260
  • 10
  • 45
  • 79

5 Answers5

101

var is not a keyword according to this list.

it is a contextual keyword, so from the context, the compiler is able to decide which is your class and which is the contextual keyword, and no confusion arises.

a contextual keyword is:

used to provide a specific meaning in the code, but it is not a reserved word in C#.

so as it's not reserved you can use it.

As pointed out in the comments above there is a discussion of the differences as well as a list of the various keywords and contextual keywords added at each version of c# on Eric Lippert's blog

It is interesting to note that since the set of keywords was decided upon in C#1.0 there have been no additions, so as to preserve backward compatibility.

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
  • 1
    However it's categorised under "C# Keywords" here http://msdn.microsoft.com/en-us/library/bb383973.aspx ... confusing! – Richard May 11 '12 at 09:46
  • 4
    But it's a [`Contextual Keyword`](http://msdn.microsoft.com/en-us/library/x53a06bb.aspx). _"A contextual keyword is used to provide a specific meaning in the code, but it **is not a reserved word in C#**. Some contextual keywords, such as partial and where, have special meanings in two or more contexts."_ – Tim Schmelter May 11 '12 at 09:46
  • 5
    @TimSchmelter Then "var" is a "keyword". Just not a "reserved word", right? – luiscubal May 11 '12 at 11:03
  • @luiscubal as it says on the linked page its a contextual keyword, not a reserved keyword. The linked post of Eric Lippert's blog explains it in more detail than the MSDN article. – Sam Holder May 11 '12 at 11:07
  • 2
    I'm guessing it's to maintain compatibility with old code - if someone had a class named `var` then not everything breaks when upgrading C#. – Callum Rogers May 14 '12 at 08:42
  • 1
    @CallumRogers: that's _exactly_ why the C# team did this. Same for other later introduced "keywords" like from, join etc (all contextual by the way). – Abel May 15 '12 at 17:38
  • grammar mistake: it is 'able' not 'be able'. – trinalbadger587 Apr 16 '16 at 08:42
  • Thanks @trinalbadger587 fixed – Sam Holder Apr 16 '16 at 09:46
18

The compiler is smart enough to know that the context you are using var as a class name is never a context for the keyword so allows it (which is why it is defined as a contextual keyword).

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • I think this answer is at least somewhat misleading. The compiler is not exactly "smart enough" to determine whether `var` is being used as a keyword in code like `var testVar = new var();`. Yes, the context, in terms of whether a custom type named `var` was defined, plays into it, but it's precisely because the compiler is *not* smart enough in those cases to know whether `var testVar` refers to the class `var` or to the keyword `var` that it defaults to the class in such a context. Were the `var` keyword named differently, it could be used in the very same "context". – O. R. Mapper Aug 25 '14 at 08:57
  • Contrast that with other contextual keywords, such as `add` - here, the compiler indeed knows at every occurrence whether the keyword is meant (event declaration; identifier wouldn't make any sense there), or whether the code is referring to an identifier (type or name in a declaration, use of the identifier within a method body; keyword wouldn't make any sense there). – O. R. Mapper Aug 25 '14 at 09:03
12

Another way of looking at this: "var" as a keyword was not in the first versions of C# (unlike "int" and "true"), so you might have written some code then which had a class called "var". This was perfectly fine and legal. Then later on when "var" was added to the language, the designers were so kind as to make it a keyword only in certain contexts, so your existing var class would still work.

This is one of the real challenges of language design - how to add new features without breaking existing code, and without making the new features cumbersome to use.

Polyfun
  • 9,479
  • 4
  • 31
  • 39
8

In C# versions before version 3, implicitly typed local variables were not supported yet, so var had no special meaning and it was possible to define variables and classes named var. Your example program is legal, because both occurrences of var in main referred to the class var.

C# 3 and later versions are downwards compatible, so code written in C# before version 3 still compiles with the new compilers.

int and true are keywords since C# 1.

dtb
  • 213,145
  • 36
  • 401
  • 431
3

Keywords can be reserved contextually. When the source code is parsed, that context is established as part of the parse tree. The evaluation of keywords takes place within that context. So, in this case, var isn't in a reserved context and won't have the same meaning as when you're using it in an assignment statement. I believe one reason for this flexibility is that var was introduced in C# 3, so making it reserved everywhere might have broken backwards compatibility in some programs, whereas using it as a variable type declaration wouldn't have compiled in earlier versions, so there's no breakage.

pfries
  • 1,720
  • 12
  • 14