OdeToCode IC Logo

Once More In Defense Of The var Keyword

Tuesday, February 8, 2011

Even today there are those of you who doubt the power of the var keyword in C#! Or rather, there are those of you who steadfastly refuse to use it.

I think the var keyword provides a nice symmetry for local variable declarations. No one variable appears more important than another just because it has a type name with more capital letters.

var newPatient = new Patient();
var surgicalProcedure = Procedures.Rhinoplasty;
var lengthOfStay = TimeSpan.FromDays(2);

We can also talk about readability, type inference - blah blah blah. But, I think the following generalization is the real benefit of the var keyword.

Developers who use the var keyword tend to take greater care in naming their variables.

I think the carefulness is a natural reaction to the lack of type information.  I've seen quite a bit of code like this:

Procedure proc = Procedures.Rhinoplasty;

But, rarely do I see abbreviations and shortcuts with var.

var surgicalProcedure = Procedures.Rhinoplasty;

If you are still wary of var, give it a try for the day. I think your variable names will thank you.

Anonymous Tuesday, February 8, 2011
(sigh) So once again, we are defending the pervasive use of a keyword that was intended primarily for use out of necessity (namely, when declaring instances of anonymous types) because it supposedly encourages you to name your variables more clearly (which you should be doing *anyway*) while really, you are just littering your code with mental "speed bumps" for the next poor bastard who has to come behind and figure out WTF type you just declared?

I'm sorry, under NO circumstance is this:

var numberOfEmployees = ...

better than this:

int numberOfEmployees = ...
Gravatar Markus Zywitza Tuesday, February 8, 2011
I like to use the type name due to R# helping me in using good names w/o typing to much

Pro<CTRL-Space><Enter> surgical<CTRL-Space><Enter>=Pro<CTRL-Space><Enter>.R<CTRL-Space><Enter>

will become
Procedure surgicalProcedure = Procedures.Rhinoplasty

With var, R# won't complete my variable names, that lazy me tends to use p rather Prodecure in this case...
Oren Novotny Tuesday, February 8, 2011
@Anonymous -- what about complex generics:

var citiesByState = GetMap();

is more clear than

IDictionary<string, IEnumerable<string>> citiesByState = GetMap()

or even

IDictionary<string, IEnumerable<KeyValuePair<string, int>>> citiesByStateWithSize = GetMap()

The generics get in the way of the meaning
Gravatar Gary McAllister Tuesday, February 8, 2011
Get functional or die trying.
Gravatar Chris Missal Tuesday, February 8, 2011
Let's not forget that changing a return type would also force us to change every spot where the type name is used. So when something like numberOfEmployees changes from an int to something more useful, you're still good. There's one circumstance @Anonymous.
Gravatar Rob Seder Tuesday, February 8, 2011
@Oren - that should be wrapped in a container class first of all. Perhaps:

StatesWithSizeCollection citiesByState = GetMap();

Second of all, @anon is correct on all counts. The abuse (not use) of var, leads to lots of problems.

Unless you are in academia, MOST developers see "var" as a shortcut, not a tool. If they were to "lazy" to write out the declaring type, what makes you think they will suddenly be motivated to use quality variable names? Instead, you see "var object = ..." or "var o = ...". If you think this doesn't happen, you are either working for a strict software company or you work in a college. This absolutely happens in the other 95% of the programming world!

Var has a VERY specific purpose for TRUE dynamic typing. If you are using it any other place, it's out of laziness, IMHO.

Also, @Chris - under what circumstance would you change the return type and you "not care" about all the places where it's referenced? I would absolutely, positively want the my code to break if I change the return type so that I can review all the places it was referenced.

Var is the VB6 "variant", all over again!!
bhofmann Tuesday, February 8, 2011
Did someone mention refactoring? When my code uses "var" rather than a specified type, I can change the resulting types (so long as they offer the same interface) and the code that uses the changed library doesn't need checking out and changing.
Gravatar Andy Sherwood Tuesday, February 8, 2011
Personally, I only use var when the return type is totally obvious. Otherwise, I find myself diving into the object browser or Reflector to figure out what I'm getting back.

var session = new Session();
var surgicalProcedures = session.Load<SurgicalProcedure>();

var session = Session.Default;
var surgicalProcedures = session.LoadSurgicalProcedures();

In your example, I would write:

var newPatient = new Patient();
SurgicalProcedure surgicalProcedure = Procedures.Rhinoplasty;
DateTime lengthOfStay = TimeSpan.FromDays(2);

Jer0enH Tuesday, February 8, 2011
@Andy Sherwood: except that last line would not even compile :-P
Matt Tuesday, February 8, 2011
Why the f*** is this even an issue? There are plenty of other production quality languages where type inference is not only encouraged, but declarative typing is DISCOURAGED (ie. F#). If the compiler says its possible, I'm happy to rely on it.

You're tests should catch any untoward effects (although I've NEVER seen a bug in my code due to unwanted polymorphism or other typing error). You are testing your code, right?

Welcome to the 21st century.
Gravatar Matt Briggs Tuesday, February 8, 2011
IMO the primary gain is the DRY principal. code like XmlEnterpriseParserFactoryBuilder xmlEnterpriseParserFactoryBuilder = new EnterpriseParserFactoryBuilder<EnterpriseBuilderStrategy>(EnterpriseFactoryBuilder.CONST) is a _nightmare_.

That is an extreme case (but extremely plausible). Even in common cases, all you are doing is repeating information that is already written. it is like saying "Greeting Paul Hi Paul!" in english.
Gravatar Elliott O'Hara Tuesday, February 8, 2011
The reason one might hate using the var keyword.
* I don't understand the difference between variant and implicit typing
* I like writing code that doesn't do anything.
* I don't believe in refactoring
* I think polymorphism is a silly word
* I don't understand polymorphism
* I think OOP is for nerds
* I don't understand polymorphism
* I don't understand polymorphism
* I don't understand polymorphism
* see above
Gravatar Chris Nicola Tuesday, February 8, 2011
It amazes me that this discussion even needs to take place. Why in 2011 are .NET devs still debating whether it is ok to use var?

1) var is perfectly type safe, not using it communicates nothing of vital importance. It is not duck-typing and it is not dynamic (on that note, heaven forbid we even discuss the value of 'dynamic' with people who have yet to accept 'var'). If you simply don't like it fine, but stop pretending it is bad for any reason other than your personal preference (which is an outdated preference at best)

2) Do we really not have bigger fish to fry than whether or not it's ok to use var?
Foothills Tuesday, February 8, 2011
int a = 3, b = 4;
var c = a + b;
a = c;

Why shouldn't I use var for c? If I change the type of a and b, c's type changes automatically and does not affect the meaning of the code. As long as c's type is the same as that of a and b, the specific type is irrelevant.

If I don't use var, I run the risk of changing the type of a and b but forgetting to change c. Now I'm relying on a compiler warning (hopefully) to catch my mistake. It's better to be in a situation where the mistake is not possible in the first place.

However, if my code somehow made use of, say, Int32.MaxValue, then the code would be affected if its type changed, and I would not use var.

Also, the fact that the return type is unclear is exactly the point sometimes:

var list1 = GetSomeList("foo");
var list2 = GetSomeList("bar");
foreach (var z in list1) {

This code does not care what the type of z is, and that is the point. Adding type information would get in the way of the intent and make it more difficult to refactor. The type stored in list1 and list2 does not matter.

Yes, this could be done with a generic class, but you might not have that option, and why write an entire class to iterate over a collection when 3 lines of code will do? The point here is to write change-resistant code, not to create a reusable abstraction.

Also, try looking at static, type-inferenced languages such as Haskell, OCaml, F#, and Scala. They do just fine with all of their "laziness."
Gravatar Aaron Jensen Tuesday, February 8, 2011
Dear those complaining about var,

Please spend a week or two in a dynamic language (try Ruby). Be sure to really learn it, write something real, with real tests. Maybe two weeks isn't enough. Take a few months.

Then come back to C# and give us your thoughts on the var keyword. Your most likely response: "Ugh, I hate typing var, why can't we just have Option Implicit!"

Also, the amount of FUD/just plain wrong statements in this comment thread is sickening. var is nothing more than a shortcut, it's not dynamic typing, it's not VB's variant. It's a lovely shortcut too. I see no reason to ever *not* use var. Want to know the type? Hover over it the variable.
Gravatar Rik Hemsley Tuesday, February 8, 2011
Because we're not in the bottom 95%, son.
Gravatar Jeremy Tuesday, February 8, 2011
As a member of the .NET community, I am frankly embarrased by the misinformation, misunderstanding, myopia and conscious ignorance displayed whenever this and related subjects come up. A good number of the commenters here and elsewhere have not only completely misunderstood how var works but have also obviously never worked with a language that encourages or requires implied typing, static or otherwise. Heaven help us if these people ever find themselves trying to do any deeply functional programming and, yes, by that I am including any complex LINQ. That they are also happy to repeatedly trumpet their ignorance is a true shame.

@Aaron - I'll go one step farther regarding your point on hovering: Sure, go ahead and make the odd variable type explicit where it adds significant clarity. Sure, go ahead and hover over the occasional query result variable to make sure you did produce your desired type. But if someone has a constant need to see the exact types of every one of their variables, their code is already screwed and var is neither the cause or cure.
Anonymous Tuesday, February 8, 2011
Wow, the flames are flying even hotter and faster than I expected when I originally posted. :) I stand by what I said, but I'll add couple of points:

* I understand that var is not dynamic typing, and it is not equivalent to the infamous VB Variant type. Several seemed to imply that anyone who is opposed to the use of the var keyword -- for ANY reason -- doesn't know the difference, or doesn't understand polymorphism. This simply isn't true.

* Speaking of polymorphism, I would argue that using var for this purpose is obscure at best. There are better and clearer ways to do this in C# (e.g. interfaces and abstract classes). And surely you understand that in the following code...

A1 foo = new A2();

...that A1 and A2 are actually *different things* from a language perspective? Namely, a declared type and an instantiated type?

* I understand that there is a vocal segment of the .NET developer community that is so consumed with Ruby Envy (tm) that they can't see past their own ergonomic keyboards. I get it. I've written Ruby. Ruby is nice. But we are talking about C# here. I don't think that attempting to morph one language with a given paradigm into another completely different one is healthy for the language. You want super-terse syntax and dynamic typing? REALLY hate C#'s verbosity? Then maybe C# isn't for you.

* If you *really* want dynamic typing in C#, then use the dynamic keyword. That way, you are explicitly expressing your intent that the variable in question is going to be flying crazy and loose for the rest of its lifetime.
Gravatar Filini Wednesday, February 9, 2011
Aaron Jensen is 100% right.

This is a flame war that is only supported by people who don't understand what "var" is in C#. It's just syntactic sugar, nothing like variant or dynamic. The compiler will translate it to the type returned by the right-side statement.

There isn't a single reason for this discussions to exist :)
dan Wednesday, February 9, 2011
I don't understand why

int numberOfEmployees = ...

is better than

var numberOfEmployees = ...

The variable name tells me it is a positive whole number. What more do I need to know when reading the code?

Gravatar Elliott O'Hara Wednesday, February 9, 2011
The fact that someone wants his code to "break" because someone changed a type speaks volumes to me.

Every argument against using var is rooted in the thought process that somehow the type of an object is more important that what an object DOES.

That thought process is the result of a lack of understanding of OOP, period. End of story.

Be offended, of become a better software engineer, the choice is yours.
Gravatar Dan Martin Thursday, February 10, 2011
People still argue against var? Maybe next we can argue MVC vs Webforms or whether the Earth is flat or not... :)
Bryant Brabson Friday, February 11, 2011
Quoting Chris Nicola:

"It amazes me that this discussion even needs to take place. Why in 2011 are .NET devs still debating whether it is ok to use var?"

My thoughts exactly! Move along, nothing to see here.
Kit Friday, February 11, 2011
I like the symmetry argument. Assignment to variables does not convey the intent of the code as much as what you do after that, so an unnatural attraction of my eye to longer type names detracts (noise) from the logic (signal) of the method.

Not using var almost feels like the use of Hungarian naming in a different form. If I really need to know the type *that* bad, the tools I use can reveal it quickly enough. If I need to do that though, I have to wonder whether this is a readability failure of the original author.

Var does seem to promote better naming; it does result in fewer check-ins ( a big plus); it's easier to type and DRY.

My vote is yes to time saved writing, time saved reading, time saved scrolling right, and general pleasure of its aesthetic leveling of the "act of assigning something to a variable".
Gravatar Kyralessa Saturday, March 5, 2011
The argument that puzzles me most is the "laziness" argument. If a developer isn't picking good variable names, it doesn't matter whether the developer uses var or not.

Dictionary<string, object> result = GetResult();

That doesn't become a worse line if it uses var. It doesn't become a better line for using Dictionary<string, object>. A bad variable name is a bad variable name.
Comments are closed.