views:

715

answers:

11

Possible Duplicates:
C# 'var' keyword versus explicitly defined variables
C# - Do you use "var"?

This is a relatively simple question...more of a poll really. I am a HUGE fan of C#, and have used it for over 8 years, since before .NET was first released. I am a fan of all of the improvements made to the language, including lambda expressions, extension methods, LINQ, and anonymous types. However, there is one feature from C# 3.0 that I feel has been SORELY misused....the 'var' keyword.

Since the release of C# 3.0, on blogs, forums, and yes, even Stackoverflow, I have seen var replace pretty much every variable that has been written! To me, this is a grave misuse of the feature, and leads to very arbitrary code that can have many obfuscated bugs due to the lack in clarity of what type a variable actually is.

There is only a single truly valid use for 'var' (in my opinion at least). What is that valid use, you ask? The only valid use is when you are incapable of knowing the type, and the only instance where that can happen:

When accessing an anonymous type

Anonymous types have no compile-time identity, so var is the only option. It's the only reason why var was added...to support anonymous types.

So...whats your opinion? Given the prolific use of var on blogs, forums, suggested/enforced by tools like ReSharper, etc. many up and coming developers will see it as a completely valid thing.

  • Do you think var should be used so prolifically?
  • Do you think var should ever be used for anything other than an anonymous type?
  • Is it acceptable to use in code posted to blogs to maintain brevity...terseness? (Not sure about the answer this one myself...perhaps with a disclaimer)
  • Should we, as a community, encourage better use of strongly typed variables to improve code clarity, or allow C# to become more vague and less descriptive?

I would like to know the communities opinions. I see var used a lot, but I have very little idea why, and perhapse there is a good reason (i.e. brevity/terseness.)

+12  A: 

I think it should be used in those situations where the type is clearly specified elsewhere in the same statement:

Dictionary<string, List<int>> myHashMap = new Dictionary<string, List<int>>();

is a pain to read. This could be replaced by the following with no loss of clarity:

var myHashMap = new Dictionary<string, List<int>>();
Samir Talwar
If you do that, what 'type' is displayed as a tooltip when the mouse hovers over a mention of the variable?
ChrisW
HashMap<String, ArrayList<int>> I believe.
ChrisF
lol, ChrisF and ChrisW
Carson Myers
Your assuming code is always read with Visual Studio. Where I work, developers choose their own development environment. We have notpadders, VI users, emacs lovers, etc. When you read a complex code example on a blog, say something that uses a LINQ query...you don't have intellisense, and the type represented by a var variable is often unclear (yet an understanding of the underlying type is expected to understand the code example.) You also can't forget that old classic...printed sheets of code.
jrista
@jristra: I think your situation is pretty rare. Most would not choose to develop in C# and not us VS, and who is printing pout reams of C# code?
Ed Swangren
I'm confused. Even if you were reading your code on paper, how would using var confuse people? The type is clearly stated after the `new` operator.
Samir Talwar
C# devs using VI - Call someone in a white coat to come and get them, they are clearly insane, and a danger to themselves and everyone around them.
Tim Jarvis
I wouldn't let a c# developer work in notpad merely because their productivity couldn't come near an equally skilled dev in a real IDE.
SnOrfus
+3  A: 

Never say never. I'm pretty sure there are a bunch of questions where people have expounded their views on var, but here's mine once more.

var is a tool; use it where it's appropriate, and don't use it when it's not. You're right that the only required use of var is when addressing anonymous types, in which case you have no type name to use. Personally, I'd say any other use has to be considered in terms of readability and laziness; specifically, when avoiding use of a cumbersome type name.

var i = 5;

(Laziness)

var list = new List<Customer>();

(Convenience)

var customers = GetCustomers();

(Questionable; I'd consider it acceptable if and only if GetCustomers() returns an IEnumerable)

Rob
I consider your "Questionable" verion to be allowed. Makes for much simpler refactoring and faster development to allow the compiler to figure out the typing.
Matthew Whited
+4  A: 

Read up on Haskell. It's a statically typed language in which you rarely have to state the type of anything. So it uses the same approach as var, as the standard "idiomatic" coding style.

If the compiler can figure something out for you, why write the same thing twice?

A colleague of mine was at first very opposed to var, just as you are, but has now started using it habitually. He was worried it would make programs less self-documenting, but in practice that's caused more by overly long methods.

Daniel Earwicker
I've read about Haskell, and I have been using F# for a lot of personal projects. Both of those languages use type inference "idiomatically"...it just how those languages are used. With C#, in my experience, with a large dynamic and growing team of developers, var leads to a lot of confusion and lack of clarity.
jrista
But how does it cause those problems more in C#? Prior to var, it wasn't an idiomatic choice in C# because there was no such feature, so you had to write the type. So you can't argue that people rationally chose that way of writing declarations for some good reason. They had no other way. Now they have a choice, and it's identical to the choice available in F# and Haskell, and the constraints/benefits/disadvantages are identical. So that's why it's becoming accepted style in C# too.
Daniel Earwicker
A: 

As Earwicker indicated, there are some functional languages, Haskell being one and F# being another, where such type inference is used much more pervasively -- the C# analogy would be declaring the return types and parameter types of methods as "var", and then having the compiler infer the static type for you. Static and explicit typing are two orthogonal concerns.

In fact, is it even correct to say that use of "var" is dynamic typing? From what I understood, that's what the new "dynamic" keyword in C# 4.0 is for. "var" is for static type inference. Correct me if I am wrong.

harms
Yes, var is for (very elementary) static type inference, nothing dynamic about it.
Alex Martelli
+1  A: 

If you feel that giving the same information twice reduces errors (the designers of many web forms that insist you type in your email address twice seem to agree), then you'll probably hate var. If you write a lot of code that uses complicated type specifications then it's a godsend.

EDIT: To exapand this a bit (incase it sounds like I'm not in favour of var):

In the UK (at least at the time I went), it was standard practice to make Computer Science students learn how to program in Standard ML. Like other functional languages it has a type system that puts languages in the C++/Java mould to shame.

Anyway, what I noticed at the time (and heard similar remarks from other students) was that it was a nightmare to get your SML programs to compile because the compiler was so increadibly picky about types, but once the did compile, they almost always ran without error.

This aspect of SML (and other functional languages) seems to be one the questioner sees as a 'good thing' - i.e. that anything that helps the compiler catch more errors at compile time is good.

Now here's the thing with SML: it uses type inference exclusively when assigning. So I don't think type inference can be inherently bad.

U62
I've been using F# (which is a derivative of ML), and I definitely like it. It provides extremely terse code. However, inferred type is idiomatic in F#...its not really idiomatic in C#, and there is a difference between imperative programming (C#) and declarative/functional programming (F#, ML): The latter is based on the concept of variable immutability. I think thats an important factor in type inference.
jrista
+7  A: 

Pop quiz!

What type is this:

var Foo = new string[]{"abc","123","yoda"};

How about this:

var Bar = {"abc","123","yoda"};

It takes me roughly no longer to determine what types those are than with the explicity redundant specification of the type. As a programmer I have no issues with letting a compiler figure out things that are obvious for me. You may disagree.

Cheers.

another average joe
Your thinking about you reading your code. But what about someone else reading your code? Particularly someone new to a project and/or the C# language? Var reduces clarity, particularly for the latter case. I can easily see scenarios where Foo would be misunderstood as a string (rather than string[]), and Bar misunderstood as an object[] rather than a string[].
jrista
@jrista, a coder's job is to be concise and clear _to somebody who knows the language_, NOT to use unbounded amount of boilerplate to try and be readable by those who don't know the language (a hopeless task anyway). So, a +1 to counteract your downvote, and, long live var!-)
Alex Martelli
@alex: "a coder's job is to be concise and clear _to somebody who knows the language" - say that to yourself the next time you get a 5 line statement, compressed into 1 line, without spacing; but "you know the language don't you, and it compiles doesn't it?" Readability is not related to whether or not it compiles.
SnOrfus
@ SnOrfus: I don't think Alex was saying anything is acceptable if it compiles. His argument was actually very good...for the most part, its the job of the developer to be concise and clear. My whole reason for starting this, apparently highly controversial, post was due to the fact that I encounter a lot of junior coders, and 'var' misuse has lead to considerably more bad code than misuse of other features like linq.
jrista
+1  A: 
var MyCustomers = from c in Customers 
                  where c.City="Madrid" 
                  select new { c.Company, c.Mail };

If I need only Company and Mail from Customers collection. It's nonsense define new type with members what I need.

MicTech
I think your missing new { ... } in your select statement. But the example you have there is exactly the scenario that var was designed for...anonymous types. MyCustomers has no compile-time type...so var is the only option, and is an acceptable use. :)
jrista
It does have a compile-time type, just an anonymous one. See my answer and Martelli's comment to it. See also U62's edited answer regarding SML.
harms
This is the one 'valid' case, as per the question.
FryGuy
+1  A: 

I agree with others that var eliminates redundancy. I have decided to use var where it eliminates redundancy as much as possible. I think consistency is important. Choose a style and stick with it through a project.

Matt Spradley
"As much as possible" may be excessive -- I'd stick to "where it removes duplication" (repetitiousness, redundancy).
Alex Martelli
I agree with Alex that if var can be used to support the DRY concept, then its probably a good use. It strongly disagree that it should always be used.
jrista
+7  A: 

var is a splendid idea to help implement a key principle of good programming: DRY, i.e., Don't Repeat Yourself.

VeryComplicatedType x = new VeryComplicatedType();

is bad coding, because it repeats VeryComplicatedType, and the effects are all negative: more verbose and boilerplatey code, less readability, silly "makework" for both the reader and the writer of the code. Because of all this, I count var as a very useful enhancement in C# 3 compared to Java and previous versions of C#.

Of course it can be mildly misused, by using as the RHS an expression whose type is not clear and obvious (e.g., a call to a method whose declaration may be far away) -- such misuse may decrease readability (by forcing the reader to hunt for the method's declaration or ponder deeply about some other subtle expression's type) instead of increasing it. But if you stick to using var to avoid repetition, you'll be in its sweet spot, and no misuse.

Alex Martelli
Very good point about DRY. So long as what your setting your variable to clearly describes the type, then I can see the benefit.
jrista
A: 

I must admit when i first saw the var keyword pop up i was very skeptical.

However it is definitely an easy way to shorten the lines of a new declaration, and i use it all the time for that.

However when i change the type of an underlying method, and accept the return type using var. I do get the occasional run time error. Most are still picked up by the compiler.

The secound issue i run into is when i am not sure what method to use (and i am simply looking through the auto complete). IF i choose the wrong one and expect it to be type FOO and it is type BAR then it takes a while to figure that out.

If i had of literally specified the variable type in both cases it would have saved a bit of frustration.

overall the benefits exceed the problems.

Bluephlame
You mentioned a benefit was shortened line length, but you have failed to provide any benefit that would outweigh the problems that arise from use of var. You have provided two that cause compile-time problems which wouldn't exist if you had not used var...but where are the counterpoints? What benefits of using var exceed those problems?
jrista
@jrista: I have yet to see the problems you are whining about... And I call it whining becasue you have put a complaint in pretty much every answer.
Matthew Whited
I have put a response in every answer, but hardly "complaints". Apparently I've hit a major nerve with people, particularly you, it seems. Check the hostility man...my intent was to spark discussion, not start a war.
jrista
A: 

I have to dissent with the view that var reduces redundancy in any meaningful way. In the cases that have been put forward here, type inference can and should come out of the IDE, where it can be applied much more liberally with no loss of readability.

CurtainDog