The evilness of 'var' in C#? [duplicate]
Asked Answered
F

11

10

Possible Duplicate:
C# 'var' keyword versus explicitly defined variables

EDIT:

For those who are still viewing this, I've completely changed my opinion on var. I think it was largely due to the responses to this topic that I did. I'm an avid 'var' user now, and I think its proponents comments below were absolutely correct in pretty much all cases. I think the thing I like most about var is it REALLY DOES reduce repetition (conforms to DRY), and makes your code considerably cleaner. It supports refactoring (when you need to change the return type of something, you have less code cleanup to deal with, and NO, NOT everyone has a fancy refactoring tool!), and anecdotally, people don't really seem to have a problem not knowing the specific type of a variable up front (its easy enough to "discover" the capabilities of a type on-demand, which is generally a necessity anyway, even if you DO know the name of a type.)

So here's a big applause for the 'var' keyword!!


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.)

Fahrenheit answered 23/5, 2009 at 21:51 Comment(6)
All variable type declarations inside a function body should be eliminated. Var is one step in that direction. If F#, OCaml, and Haskell can do it, why can't C#?Perennate
Duplicates: https://mcmap.net/q/15983/-use-of-var-keyword-in-c and stackoverflow.com/questions/633474/c-do-you-use-varAdorable
Heh... Duplicate, and argumentative to boot. @jrista: ever consider that maybe it's heavily used in code listings to reduce line length? Not everyone's using full-sized windows on 20" screens...Paulettapaulette
"ever consider that maybe it's heavily used in code listings to reduce line length?" If you had actually read my post rather than just bashing it as "argumentative", you would realize the answer to that already. Quote from my own post: "Is it acceptable to use in code posted to blogs to maintain brevity...terseness?"Fahrenheit
This questioner is going to get REALLY mad when he hears about those "dynamic" typing language things kids are doing these days!Shiekh
Some negatives of var. You can't tell what type this is: "var whatIsMyType = GuessWho();". You can wrongly assign variables easier: "var myShort=257; sendAShort(myShort); // exception thrown because var is not a short".Sandoval
K
24

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.

Kwangju answered 23/5, 2009 at 21:51 Comment(3)
Very good point about DRY. So long as what your setting your variable to clearly describes the type, then I can see the benefit.Fahrenheit
This case would be more realistic as VeryComplicatedType veryComplicatedType = new VeryComplicatedType();Vinegarette
var x = new VeryComplicatedType(); is more bad coding.Greenness
P
24

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>>();
Photosphere answered 23/5, 2009 at 21:51 Comment(11)
If you do that, what 'type' is displayed as a tooltip when the mouse hovers over a mention of the variable?Signature
HashMap<String, ArrayList<int>> I believe.Adorn
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.Fahrenheit
@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?Portraiture
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.Photosphere
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.Anthesis
@Tim : you clearly are not a user of either Vi or Emacs then. Or maybe you tried them for a few days and gave up. While I agree that VS has great features, it is still far from the power of these aforementioned editors when it comes to pure edition. Vi/Emacs lacks semantic navigation which is a flaw in large, unknown code bases.Robin
@Samir: var would confuse someone in a circumstance such as: var whatIsMyType = GuessWho();Sandoval
@DougS: Sure, but that's not what I said. Please read my answer before criticising it.Photosphere
@Samir: That IS what you said: "how would using var confuse people? The type is clearly stated after the new operator." And as my comment shows, the type is not always stated after the new operator.Sandoval
@DougS: The comment should be taken in the context of the example I gave. In the example, it is. It's not generalisable.Photosphere
B
10

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.

Balmung answered 23/5, 2009 at 21:51 Comment(6)
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[].Fahrenheit
@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!-)Kwangju
@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.Anthesis
@ 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.Fahrenheit
Pop quiz, take 2! What type is this: var whatIsMyType = GuessWho();Sandoval
var Bar = {"abc","123","yoda"}; gives errors.Greenness
S
6

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)

Shouse answered 23/5, 2009 at 21:51 Comment(1)
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.Cynic
A
4

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.

Anet answered 23/5, 2009 at 21:51 Comment(2)
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.Fahrenheit
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.Anet
C
3
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.

Calash answered 23/5, 2009 at 21:51 Comment(3)
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. :)Fahrenheit
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.Hysterectomize
This is the one 'valid' case, as per the question.Huntress
O
1

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.

Orenorenburg answered 23/5, 2009 at 21:51 Comment(2)
"As much as possible" may be excessive -- I'd stick to "where it removes duplication" (repetitiousness, redundancy).Kwangju
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.Fahrenheit
H
1

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.

Hatshepsut answered 23/5, 2009 at 21:51 Comment(1)
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.Fahrenheit
M
0

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.

Maurreen answered 23/5, 2009 at 21:51 Comment(0)
G
0

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.

Gavrila answered 23/5, 2009 at 21:51 Comment(3)
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?Fahrenheit
@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.Cynic
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.Fahrenheit
H
0

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.

Hysterectomize answered 23/5, 2009 at 21:51 Comment(1)
Yes, var is for (very elementary) static type inference, nothing dynamic about it.Kwangju

© 2022 - 2024 — McMap. All rights reserved.