Skip Navigation LinksHome > View Post

To var or not to var

Visual Studio 2008 introduced plenty of compiler magic to .NET such as automatic properties:

public string Name { get; set; }

... and class initializers:

Product product = new Product() { Name = "Lemon Gin", Price=135 };

(Bruusi mentioned before why he prefers constructors for this sort of thing, and I agree.)

We also saw the introduction of anonymous types and the var keyword.

var theDaddy = new { Name = "Morgan", SplashFactor = 10 };

What's particularly great about all this is, because these features are just compiler trickery, we can use them with good old .NET 2.0!

Back to the subject of the post... Here's the thing though, you can use the var keyword with non anonymous types too.

var product = new Product() { Name = "Lemon Gin", Price=135 };

I recently got my hands on a copy of ReSharper 4.0 and the use of var in this way for local variables is a default recommendation made by ReSharper:

ReSharper suggesting the use of var

It's easy enough to turn this feature off using the highlighted option on the smart tag menu shown above. And at first, I was appalled and very nearly turned it off: "What on earth? Surely that's not what the var keyword is for!" However, I decided to give this approach a chance and, over time I grew to like it. This "to var or not to var" argument caused something of a minor poo-storm in my team recently with the salient points going something like this:

Arguments for:

  • It makes the code easier to read

Arguments against:

  • It's lazy
  • I need to know what type of variable I'm dealing with and that should be clear when it's declared (the counter argument is that the type is right there on the right hand side of the assignment)
  • It doesn't encourage interface based programming, e.g. IMyInterface obj = new MyImplmentation();
  • It's just wrong
For me, there isn't a technical argument here only one of preference and I am open to both approaches. For now, for the sake of convention, I'm going to side with the majority, so where do you stand? I'm also curious to gauge how this changes over time, so vote now:

The question

If you can't see the survey please click here. It's tiny and will only take you a second.

Tags: C#

 
Josh Post By Josh Twist
4:32 AM
18 Jul 2008

» Next Post: More on to var or not to var
« Previous Post: Anonymous Delegates, how I love thee

Comments are closed for this post.

Posted by Ryan Lanciaux @ 18 Jul 2008 6:51 AM
I think it's like a lot things in programming ... it depends :) I like it for getting rid of redundant code. When you have things like var o = new Object(); it makes sense to not have to say o is an Object twice imo.

Posted by Ryan Simpson @ 18 Jul 2008 7:11 AM
Instead of var, surely 'er' would have been better. If you were really unsure, you could then make it nullable 'er?'

Posted by Cassio @ 18 Jul 2008 7:34 AM
If you have a factory to initialize your var variable it becomes a little harder to know the type you're initializing. Specially if you have a lot of factory classes. Nevertheless I think it's ok. :)

Posted by Tom Ballard @ 18 Jul 2008 7:38 AM
I think var is nice for generated business entity code, and things where the type is incidental.

Posted by James World @ 18 Jul 2008 7:41 AM
I wonder if the motivation for var hatred its name is reminiscent of the weakly-typed COM variants. It's easy to jump to the mistaken conclusion that vars are weakly typed. The "variable" aspect of a var is strictly its value and not its type, unlike COM variants. Personally I'm not that bothered; I don't think it causes type confusion so I use it when it makes my code look prettiest.

Posted by Mischa @ 18 Jul 2008 8:25 AM
Many times you write the same .NET type twice in the same line of code when you declare a variable and create a new instance of it. So this one:

MyType my = new MyType();

can safely be replaced by

var my = new MyType();

because it's clear what will be the type of the variable. Results of methods or properties should not be declared with ty var statetement.

var my = Factory.CreateType();

This should be avoided. But ... as always just my personal opinion.

Posted by Fred @ 18 Jul 2008 9:03 AM
Agree with Mischa, we should use it then we can know where it does not fit it, then we know the pattern of using it.

Posted by Granville Barnett @ 18 Jul 2008 11:21 AM
My opinion is that var should only be used for anonymous types and aggregated queries.

Why should you listen to Resharper? I hate tools that tell me how to program, turn everything off and just use it for refactoring and not its suggestions.

I will now get on my bike and pedal back to the early 90's :-)

p.s. why are these validation images so hard to make out?!

Posted by Some One @ 18 Jul 2008 1:19 PM
I agree with Granville Barnet and Mischa.

The argument that it is easy to read it not true.

var my = Factory.CreateType();

Can you tell me what type 'my' is? But if it where:

IBookRepository my = Factory.CreateType(RepositoryTypes.SqlBookRepository);

Then with ease one can say it is a Book Repository Interface.

I like R# but to suggest that "all" thing be 'var' is far reaching. I turned it off.

A simple high school rule for yes no questions is that if the word "All" is used than more thant like a false statement.

Example:
All students who make As have above average IQ scores.
Or
Students who make As may have above average IQ scores.

To suggest "All" things be 'var' is bad. And false. And not easy to read.



Posted by gee @ 18 Jul 2008 2:55 PM
why are these validation images so hard to make out?!.

Is it because the logic uses ‘var’ and the programmer got confused when reading the code? He did not know if the ICaptchaMaker returned by a factory was a ComplexCaptchaMaker or a SimpleCaptchaMaker. All he/she sees is a var x = CreateCaptchaMaker(). Well he got the Complex one and now we have a complex validation image. I'm Just joking but could using ‘var’ lead to such confusion. Building an application with the wrong end results.

Posted by gee @ 18 Jul 2008 3:01 PM
It is not a question of 'var' being a week type or a strong type. It is a strong type but more or less is the type that is inferred by the compiler the one you want. And is seeing 'var' in code going to help a programmer understand what type the var is if there is notthing to the left or right of the var to help make that assumtion? And is easy code reading where one does not have to assume.

Posted by gee @ 18 Jul 2008 3:10 PM
And when I say programmer I don't mean the one who wrote the code in the first place. You write code using 'var' hand it over to someone else. Is that person going to konw what you imply by 'var'. To me it is no different than using short names for vairables. Using a varialbe like 'x' instead of 'width'. When I see 'x' in the code it could mean anything. If I was the one who wrote the code then yes I know what 'x' means but if I give that to someone are they going to know that x means width? And remember that every time they see x. Now what if in one assembly I use x for width but in another I use x for height. Now you will need to konw that x over here means width and over there it means height.

Posted by Peter Morris @ 19 Jul 2008 1:34 AM
Why write

MultiReadExclusiveWriteSynchronizer s = new MultiReadExclusiveWriteSynchronizer();

when it is just as clear to write

var s = new MultiReadExclusiveWriteSynchronizer();

However, I only use var when constructing new instances myself, I would never use it for something like

var p = SomeFactory.CreateSomeObject(); unless it was generic

var p = SomeFactory.CreateSomeObject<Person>();


Posted by Michael Giagnocavo @ 19 Jul 2008 6:53 PM
Wow... people actually *dislike* type inference?

One of the annoyances of C# is that it still requires so much manifest typing. Return types, parameters, members - all of those should be type-inferred if desired.

Type inference for locals is just a small start...

Posted by Damon Wilder Carr @ 19 Jul 2008 8:02 PM
This issue sucks as it should not exist.

Why?

1) If your the only person looking at your code do whatever
2) If on a team that has no requirement for maximization of productivity use whatever
3) If on a team and there is some mandate to be 'good' the issue with var is an issue that cannot be in this case about preference, and it is 'learnable' to read the code just as easily with var. It must be learned by some however and it takes about 5 minutes. Install ReSharper.

The only people who dont like ReSharper cannot possible refactor at 1/10th where they should. This means it fails the condition of optimization.

Nobody wants mandates and if the entire team agrees to NOT use vars that is fine. It's all or nothing unfortunately as the damages of changing around is far worse.

There is no reason to suffer what I recently quantified as a loss of a tiny 5% or so in just 'code time' which should already be small for optimizing teams.

a) Team standard MANDATES var unless it is a case where you cannot
b) ReSharper required and for the slow, they must learn why ReSharper is required. If your entire team agrees not to use it just outsource as your like so bad as to not be worth having
c) Otherwise what possible reason could there be? There is nothing gained when you have mouse-over type return to see what var is.
d) If people are forced to know all types then you have a larger problem. The code is NOT BEING REFACTORED ENOUGH. You have far too many member and/or local variables! See (1)

I've said this for about a year now and never got back an even slightly valid argument.

Those who even argue don't tend to use ReSharper or just have not forced themselves to try it for a day. Then they will never go back.

Damon Wilder Carr


a)

Posted by MuiBienCarlota @ 20 Jul 2008 3:57 AM
In this expression,

MyType my = new MyType();

you says two things:
1) i want a local strongly typed pointer to a MyType,
2) i want to allocate an instance of MyType and assign it to my local variable.

Point 1) remane as long as my is reachable.
Point 2) is only local to the line and can be located elsewhere (perhaps a factory).
Point 2) can be done several times on some other lines.

I agree that in this simple expression:

MyType my = new MyType();

one "MyType" should be enough. But i think it must be second one. Compiler can infer type in this expression:

MyType my = new ();

In this case, one can assume "same type as context".
In the other hand, it can make compiler less secure.

Posted by Mike Chaliy @ 20 Jul 2008 6:21 AM
Interesting reading on subject from ReSharper team.

http://resharper.blogspot.com/2008/03/varification-using-implicitly-typed.html

BTW, was not able to vote with IE8....

Posted by Some One @ 21 Jul 2008 2:50 PM
Damon Wilder Carr
I can remember many of projects where the first programmer thought they were the only ones who was going to look at the code. What a headache.

So after the first program is done he gets hit by the bus, person X has to step in. Well the first programmer used 'var' where ever he could. The first programmer had no problems reading it. Ok they did not get hit by a bus that was a bit extreme but they left the project for some reason. Don't be too selfish with code you might not know who will pick it up after you move on. Or maybe they wont because of the complexity in code review. To read many lines of code can only be better if 'var' is not used except with LINQ, other anonymous types, and the var object = new DataType();.

And I'm one who does use r# and turned off the 'suggestion'.

Keep in mind that your project maybe coded by one person today but why pigeon hole your project to only be programmer by one person when maybe in the future it will be read by many and reprogrammed by many. Why explain what things mean and keep in mind that the one who is to explain maybe under the bus.

Also keep in mind when I say 'read' or 'review' does not mean that the person doing it will have R# or even VS2008. One could be doing code review with notepad. As a simple rule of thumb one should be able to read code in notepad.

Posted by Some One @ 21 Jul 2008 2:57 PM
Mike Chaliy
After reading R# interpretation lets compare to what Microsoft etched in stone to see if they agree or disagree:

var (C# Reference)
http://msdn.microsoft.com/en-us/library/bb383973.aspx

Implicitly Typed Local Variables (C# Programming Guide)
http://msdn.microsoft.com/en-us/library/bb384061.aspx

Type Relationships in Query Operations (LINQ)
http://msdn.microsoft.com/en-us/library/bb397924.aspx

Posted by Some One @ 21 Jul 2008 7:34 PM
"It is important to understand that the var keyword does not mean 'Variant' and does not indicate that the variable is loosely typed, or late-bound. It just means that the compiler determines and assigns the most appropriate type."

What if the compiler does not determine and assigne the most appropriate type because there is the base type and/or and interface type.

Then to finish with:
"However, the use of var does have at least the potential to make your code more difficult to understand for other developers. For that reason, the C# documentation generally uses var only when it is required."

Then when you look at the code sample it show how and where. Now one could use var in all place but would it be easiert to read?

// Example #1: var is optional because
// the select clause specifies a string
string[] words = { "apple", "strawberry", "grape", "peach", "banana" };
var wordQuery = from word in words
where word[0] == 'g'
select word;

// Because each element in the sequence is a string,
// not an anonymous type, var is optional here also.
foreach (string s in wordQuery)
{
Console.WriteLine(s);
}

// Example #2: var is required because
// the select clause specifies an anonymous type
var custQuery = from cust in customers
where cust.City == "Phoenix"
select new { cust.Name, cust.Phone };

// var must be used because each item
// in the sequence is an anonymous type
foreach (var item in custQuery)
{
Console.WriteLine("Name={0}, Phone={1}", item.Name, item.Phone);
}

Posted by int19h @ 22 Jul 2008 10:12 AM
> It's lazy

So is using functions instead of copy/paste, and while/for instead of if/goto.

> I need to know what type of variable I'm dealing with and that should be clear when it's declared (the counter argument is that the type is right there on the right hand side of the assignment)

Hover your mouse over that "var" in VS and you'll see the inferred type. Though if you really need to know it to understand the code, then it probably needs refactoring anyway.

> It doesn't encourage interface based programming, e.g. IMyInterface obj = new MyImplmentation();

For local variables this does not have any benefits.

> It's just wrong

That's not an argument, that's a tantrum.

Posted by Paulo Morgado @ 28 Jul 2008 12:54 AM
var is very usefull when the writing the type is redundant (like when newing up a variable - as someone already posted here).

When you have several variable declarations toghether readbility is improved by having all variable names alligned.

Type inference could go a bit further, just don't go crazy:
http://msmvps.com/blogs/paulomorgado/archive/2008/04/22/stretching-type-inference.aspx

Posted by Craig Lebowitz @ 16 Aug 2008 2:37 PM
I would use where the type is obvious from reading the one line:

var someThing = new Object()
or
var otherThing = IocContainer.Resolve<CustomObject>()

but not somewhere where you need to "say" the type:

ISmtpResult d = Smtp.Forward(msg);

© 2005 - 2014 Josh Twist - All Rights Reserved.