Understanding the C# var keyword

Written on

In recent weeks I have been helping my boss to recruit for new C# developers by sitting in and asking the candidates some technical questions. One of my questions was:

Can you explain to me the C# 'var' keyword?

The var keyword was introduced in C# 3.0 several years ago, so this question wasn't considered to be a modern or difficult question (such as asking for an explanation of the more recent dynamic type) - but I was surprised how many developers didn't get it right. Plus, while browsing a MonoTouch article recently, I felt compelled to reply to an ill-informed comment where someone said "var is overused. You should strongly type your variables instead." This, along with an answer a candidate gave me in a recent interview when he said "isn't the var keyword slower?" prompts me to write this post.

I would sum it up as follows: the var keyword is a shorthand way of allowing the compiler to infer the type for you - to save your fingers some work.

Some things need to be made quite clear:

  • Using var doesn't make your variables "weakly typed". All variables declared as var are strongly typed! (C# is a statically typed language - everything is strongly typed!)
  • var isn't a type. The actual type is figured out at compile-time.
  • Due to the fact that the actual types are resolved at compile-time, the var keyword cannot be "slower".
  • It sometimes increases code readability.
  • It sometimes decreases code readability.
  • It is sometimes optional, but sometimes required.

The var keyword is not a type. System.String is a type. Int32, decimal and object are types, but var is not a type. The actual type is resolved at compile-time: it is inferred based on the right-hand-side of the equals sign. Here, the variable i is strongly typed as an integer:

var i = 3;

It is identical to typing this:

int i = 3;

In both of those examples the variable i is strongly typed as an integer. Due to that fact, this will not compile:

var i = 3;
i = "foobar";

That's right, it's not a bug, it's not "sloppy coding", or an explosion at runtime: it's a compilation error. Due to the fact that the keyword var is inferred at compile-time, this statement will not compile either:

var i;

Nor will this:

var i = null;

The last one couldn't possibly compile: what if I wanted i to be an integer, then assigning null to it doesn't make sense, it would be equivalent to this statement (which also does not compile):

int i = null;

I mentioned that there are times when the var keyword can increase code readability, but also decrease it. I think there is no need for it on the first line of code in the sample below, compared with the equivalent second line:

var i = 3;
int i = 3;

My variable i is an integer, but I haven't saved myself any keyboard strokes or saved the reader some time: I think I have slightly decreased the code readability by using var. But in the example below I think that I have increased code readability on the first line, in comparison to the equivalent second line:

var config = new List<KeyValuePair<string, string>>();
List<KeyValuePair<string, string>> config = new List<KeyValuePair<string, string>>();

In the previous two examples the use of the var keyword is optional. Whether using it results in more or less readable code is a choice that the programmer must make. Using the var keyword in the example below is not optional, it is required:

var query = customers.Select( c => new { Name = c.Name } );

That was a LINQ lambda expression returning an anonymous type. The same can be expressed using LINQ's comprehension syntax:

var query = from c in customers
            select new
                Name = c.Name

In both of those examples, an anonymous type is being returned from the LINQ expression. Don't be fooled though: even an anonymous type is strongly typed. It is another kind of "shorthand" - instead of saying (as with the var keyword) I know the type, but I'm too lazy to write it out, with anonymous types you are saying "I know the type, but I'm too lazy to create the type myself - so I'll let the compiler do it". Due to the fact that the compiler will create the type for us, we have no option but to use the var keyword to create the type.

With a new version of C# looming - developers risk falling behind the pack if they aren't even up to speed with the current version of C#.