# Monday, September 08, 2008

evil-insideWhen first I saw the var keyword in C# 3.0 I was excited, my body tingling with excitement for the possibilities this keyword would bring to the world of many a .NET developer: Productivity, clarity, fame, and fortune. Unfortunately now that C# 3.0 has been with us for a while I feel that I must warn the public of the evil that is the var keyword. Productivity, clarity, fame, and fortune have succumbed to mind boggling spaghetti code, confusion, and lets be honest fame and fortune were never really on the table to begin with :)

What then is this evil of which I speak? Massive overuse of the var keyword. Observe the following hot dish of spaghetti bolognese:

   1:  public void SpaghettiBolognese()
   2:  {
   3:      var calculator = new Calculator();
   4:      var taxLevel = GetTaxLevels();
   5:      var person = GetPerson();
   6:      var tax = calculator.CalculateTaxLevel(person, taxLevel);
   7:   
   8:      person.Tax = tax;
   9:  }

All kidding aside this piece of code breaks one of my most fundamental rules when reading and writing code: Don't make me think. Grokking a piece of code is though enough as it is having to keep types and varibles in memory (read: the developer brain) will slow down the process of code reviewing or debugging a piece of code.

For now I'm using a couple of rules to keep the var silliness at manageable levels.

1) Always use proper types for variables which are set from a method or property. It makes the code so much more readable.

   1:  Tax tax = calculator.CalculateTaxLevel(person, taxLevel);

2) Do use the var keyword when there is no question about which type it will be inferred to.

   1:  var calculator = new Calculator();
   2:  var i = 100;
   3:  var s = "Søren";

While the var keyword does offer a nice productivity gain it's important to realize when to use and more importantly when not to use it. Also it would seem that the var keyword is in cahoots with the good folks at Jetbrains as ReSharper is very eager to convert perfectly well formed type declarations to implicitly typed ones. As I started out by saying be wary of the var keyword - it's one sneaky bastard :)

Var-keywords-is-a-sneaky-bastard

Tuesday, September 09, 2008 2:55:22 AM (Romance Daylight Time, UTC+02:00)
Evil is a strong word, but I agree that "var" is nice as long as you only have to read the current line of code to infer the type, otherwise specify further.
Tuesday, September 09, 2008 6:02:51 AM (Romance Daylight Time, UTC+02:00)
Hi Søren,

I agree. Still I think that even the guidelines you state are too nice... ;) I'm talking about rule 2, example 2 and 3. Even though your examples are perfectly clear, you open the door to interpretation where people might consider things to be clear when in fact they're not.

I suggest that the guideline is rephrased to be; the keyword "var" should only be used if the inferred type is explicitly stated on the right side of the assignment.

Well, that's my 2 cents... Now I'm broke. ;)
Tuesday, September 09, 2008 9:23:31 AM (Romance Daylight Time, UTC+02:00)
Hi Søren
I never liked using "var", i'm a bit neard and like to read nice code, and if using var i can't easily see what type i'm using unless i need to release my fingers from keyboard in order to hower my mouse, to see tooltip. So i agree.
Brian Kristensen
Tuesday, September 09, 2008 9:27:37 AM (Romance Daylight Time, UTC+02:00)
Don't get me wrong. I do actually like the var keyword a great deal. Like with so many other things it's important to know when to use it and when not to :)
Tuesday, September 09, 2008 12:41:45 PM (Romance Daylight Time, UTC+02:00)
I forgot Søren, we can ask Anders when to use var when we get to JAOO :)

btw, good to see a technical post from you, i miss 'em :)
Tuesday, September 09, 2008 12:42:45 PM (Romance Daylight Time, UTC+02:00)
First of all I would never call a variable "s" or "i" (yes, in loops), but if you named your variables "name" and "age" there would be less confusion when somebody read through the code.

Second of all, why use var for declaring variables where you alreade know the type ? That would make
the code harder to read!

I would never use var for simple types (string, int, DateTime etc).

A few places where I would might use var:

1. Casts
2. Safe casts
3. Generic method calls
4. Object instantiation
5. LINQ's

Cheers
Sunday, September 14, 2008 2:13:07 AM (Romance Daylight Time, UTC+02:00)
Søren:
You mention a productivity boost, could you please specify in what way using var makes you more productive. I would rather turn your discussion around and not specify cases where "its okay" to use the keyword. I would rather ask in what situatioins its actually brings more value to my code, and to be honest. Pretty much the only place i think its justifyable is when usin anonymous types.

By the way, you can easily disable the var suggestion from ReSharper, im pretty sure its only default because they had a need to show of that they actually had C# 3.0 features in the 4.0 release as we all waited forever for it :-)

Daniel:
You write "why use var for declaring variables where you alreade know the type". Except for anonymous types you will always have to know the type of the variable to actually utilize the var keyword. Its only type inference we have not a truely dynamic type like we know from weakly typed languaes.

Monday, September 15, 2008 12:39:08 AM (Romance Daylight Time, UTC+02:00)
Well... the "Good people at JetBrains" got it ALL RIGHT!

They only offer you to convert to var as a hint (green underline) not a suggestion (green squirly line), unless the right side states the type explicit.

Just run "Cleanup code" in ReSharper (Ctrl+E+F), and all explicit types are converted to var, while implicit types are converted to the right type.

E.g. the following code:

Person personA = new Person();
var personB = GetPerson();

is converted to:

var personA = new Person();
Person personB = GetPerson();

Now you just love ReSharper even more... and if you don't like the rest of what "Code Cleanup" does, you can always configure it the way you like (remember that ReSharper supports saving your configuration in the Solution, so all other developers on that team gets the same settings).

I LOVE the var keyword, when used correct, and with ReSharper everybody om my team ALWAYS do.

: Thomas
Friday, October 03, 2008 6:47:53 AM (Romance Daylight Time, UTC+02:00)
I agree with Jakob that var is not really a huge productivity booster. However, it does improve readability in many cases, but it requires the writer to be more explicit in naming identifiers and methods.

I don't see the use of var in your example as evil. Your naming is a little confusing tough. It appears to me that your CalculateTaxLevel should really be called CalculateTax. Since taxlevel and person is (only) used as arguments for your method call there's really no reason to create local references in the first place.

I'm aware that you assign the resulting tax to person, but since you're passing a reference you could just as easily assign the proper tax in the method (and call it something like CalculateTaxForPerson). With the current implementation you may get it wrong and assign tax to one person based on the calculation for another person.

I'm very happy with the less verbose syntax allowed by the proper use of var, and in my mind the benefits clearly outnumber the caveats.
Tuesday, April 21, 2009 4:42:22 PM (Romance Daylight Time, UTC+02:00)
If I may comment also,

I'm pretty sure Søren was being rather tongue-in-cheek in his use of the term 'Evil'. However I think his points are valid. I approached the term 'var' with apprehension rather than excitement, since it was reminiscent of some VB keywords that I abhor. I was relieved to discover that 'var' wasn't that evil.

I too had heard that use of 'var' some how promoted productivity, I fail to see how. Similarly, with the exception of anonymous types, I don't really see where the use of 'var' adds clarity to my code.

If by 'clarity' everyone is referring to the sometimes rather ugly syntax needed to declare some types, particularly complex generics, as Brian mentions, 'var' may reduce the keystrokes, but does little to improve the clarity of the author's intent. If clarity and less verbose code is the goal (which sounds pretty good to me), surely some form of 'typedef' is the solution.

The comment that the "'the good people at JetBrains' got it ALL RIGHT!" is a little much. Since I would have thought the first thing you would ensure is that the project's target platform was at least 3.0 before suggesting that 'var' be employed. I agree that by default ReSharper seems a little zealous in some of it's suggestions, and I certainly appreciate it's configurable features.
Karlton Zeitz
Comments are closed.