One of the new features of C# 3.0 is the var keyword, which can be used to implicitly declare a variable’s type. For example, instead of declaring the type, you can just write var instead, and the compiler will figure out what type name should be from the value assigned to it:

// A variable explicitly declared as a certain type.
string name = "Richard";

// A variable implicitly declared as the type being assigned to it.
var name = "Richard";

Note that a var isn’t a variant, so it’s quite different from say, a var in javascript. C# vars are strongly typed, so you can’t re-assign them with values of different types:

var name = "Richard"
name = 62; // error, can't assign an int to a string

Vars were introduced to support the use of anonymous types, which don’t have type names. For example:

var me = { Name: "Richard", Age: 22 };

But there’s nothing to stop you from using vars with regular types. In a recent article on codinghorror.com, Jeff Atwood recommends using vars “whenever and wherever it makes [your] code more concise”. Guessing from his examples, this means everywhere you possibly can.

The logic behind this is that it improves your code by eliminating the redundancy of having to write type names twice — once for the variable declaration, and again for a constructor.

There’s always a tradeoff between verbosity and conciseness, but I have an awfully hard time defending the unnecessarily verbose way objects were typically declared in C# and Java.

BufferedReader br = new BufferedReader (new FileReader(name));

Who came up with this stuff?

Is there really any doubt what type of the variable br is? Does it help anyone, ever, to require another BufferedReader on the front of that line? This has bothered me for years, but it was an itch I just couldn’t scratch. Until now.

I don’t think he’s right on this one — my initial reaction is that using var everywhere demonstrates laziness by the programmer. And I don’t mean the good sort of laziness which works smarter, not harder, but the bad sort, which can’t be bothered writing proper variable declarations.

Jeff is right though – writing the type name twice does seem a little excessive. However, as Nicholas Paldino notes, the correct way to eliminate this redundancy would be to make the type name on the right hand-side optional, not the left:

While I agree with you that redundancy is not a good thing, the better way to solve this issue would have been to do something like the following:

MyObject m = new();

Or if you are passing parameters:

Person p = new("FirstName", "LastName");

Where in the creation of a new object, the compiler infers the type from the left-hand side, and not the right.

Microsoft’s C# language reference page for var also warns about the consequences of using var everywhere.

Overuse of var can make source code less readable for others. It is recommended to use var only when it is necessary, that is, when the variable will be used to store an anonymous type or a collection of anonymous types.

In the following example, the balance variable could now theoretically contain an Int32, Int64, Single (float), Double, Decimal, or even a ‘Balance’ object instance, depending on how the GetBalance() method works.

var balance = account.GetBalance();

This is rather confusing. Plus, unless you explicitly down cast, vars are always the concrete type being constructed. Let’s go back to Jeff’s BufferedReader example, of which he asks, “is there really any doubt what type of the variable br is?”

BufferedReader br = new BufferedReader (new FileReader(name));

Actually, yes there is, because polymorphism is used quite extensively in .NET’s IO libraries. The fact that br is being implemented with a BufferedReader is most likely irrelevant. All we need is something that satisfies a Reader base class contract. So br might actually look like this:

Reader br = new BufferedReader (new FileReader(name));

Just because a language allows you to do something, doesn’t mean it’s a good idea to do so. Sometimes new features adapt well to solving problems they weren’t designed for, but this is not one of those situations. Stick to using vars for what they were designed for!

June 21st, 2008 | 42 Comments
42 Responses to “C# 3.0′s var keyword: Jeff Atwood gets it all wrong” Leave your Comment
  1. Shawn says:

    Ramen.

    I read Jeff’s article yesterday and I felt the same way. We just had this battle at work and we finally decided that var was only for anonymous types.

  2. Jonathan Allen says:

    > The fact that br is being implemented with a BufferedReader is most likely irrelevant. All we need is something that satisfies a Reader base class contract. So br might actually look like this:

    That is just plain silly. Unless you have some type of branching that would allow br to be assigned a different subtype of Reader, there is absolutely no reason to explicitly give it that type.

  3. Jonathan Allen says:

    > However, as Nicholas Paldino notes, the correct way to eliminate this redundancy would be to make the type name on the right hand-side optional, not the left:

    Considering the language doesn’t support that, your argument doesn’t make much sense to me.

  4. __me says:

    OK, that is a realy bad and stupid blog posts.

  5. Chris says:

    I rather like languages with type inference. In C#, you can still put in the type tags in cases where you think there’s a real readability problem, but in a lot of cases it would be better to just fix the code :)

    Jonathan: You seem to be talking about *mutable state*. Please don’t do that except where you absolutely need to ;)

    In the Reader vs BufferedReader scenario, do you seriously want to spend effort deciding which class of an inheritance chain you want to type a variable with? `var` says “The type here is not important; Whatever type that expression happens to be, will do.”

  6. xxx says:

    > While I agree with you that redundancy is not a good thing, the better way to solve > this issue would have been to do something like the following:
    >
    > MyObject m = new();

    Whan an incredibly stupid idea. Now the RHS of the assignment doesn’t make any sense in itself. Aside from causing grave problems to the parser, this also means that you now need *two* different syntaxes for creating a new instance: one for immediate assignment like this and one for “anonymous” instance creation (as in “DoSomething(new MyObj());”).

  7. Dave says:

    I very much disagree with this blog entry. Repeating type information needlessly is fustrating and time consuming; wanting to avoid this does not make me lazy.

    I personally think type inference would make a good addition to most programming languages, including Java.

    >BufferedReader br = new BufferedReader (new FileReader(name))

    There is no confusion about the type of br here, as Jonathan Allen points out.

    > MyObject m = new();

    This is just crazy, as poster xxx points out.

  8. George Lewis says:

    This is one of those blogs that looks like it is making a rational argument, but it isn’t. At it’s core, the argument hinges upon the fact that many people are used to seeing types in C# and would feel a little anxious if they didn’t.

    The anxiety is something that they need to get over. Other people have, not only in dynamically typed languages like Python and Ruby, but also in static type-inferenced languages like Haskell, OCaml, F#, and Scala. And, let’s fact it, if you want to see the type of an expression, all you have to do is hover your mouse over the expression an the IDE will tell you what the type is.

    I’m sure that there were many people who felt lost when line numbers stated disappearing from program listings, but eventually they got over it. Growth is hard, but it is necessary.

  9. James Justin Harrell says:

    I could have sworn I once read that C# 3 was going to allow this:
    > Something s(…);
    to be used as an abbreviated form of this:
    > Something s = new Something(…);
    But a quick search didn’t turn up anything.

  10. J. B. Rainsberger says:

    True wisdom comes when you understand the difference between “That makes no sense” and “I don’t understand”.

    I would have called this article “I can’t agree with Jeff Atwood”.

    Take care.

  11. Adelle Hartley says:

    @George Lewis: What you said!

    As a (mostly) statically typed language aficionado I used to suffer dynamic-typing-language-envy whenever I wrote code like

    Dim BillsToDisplay As Bills = Bills.That.Are.Overdue

    Sometimes the the type of the expression wouldn’t always be as obvious as that, so I’d put ??? for the type and fix it up after I’ve written the assignment.

    Of course, there’s no explicit type declaration in

    MyGrid.DataSource = Bills.That.Are.Overdue

    either. I try to avoid declaring variables at all, wherever it doesn’t obfuscate my intention.

    Usually, having to declare a variable is an indication that I’ve forgotten to add a property elsewhere.

    Yeah, I realize the post was about C#, but the language feature being discussed applies to VB too.

  12. Randall Sexton says:

    Interestingly enough, I read Jeff’s blog and pretty much had the same reaction. Good post, Richard.

  13. Florian Potschka says:

    I fully agree with this article. I really like Jeffs blog posts, but I felt very discomforting with his

  14. Ricky Clarkson says:

    I think the title of this should be “Richard Dingwall gets it all wrong”.

    Specifically, if you wanted Reader r = new BufferedReader(stuff) you should write that. var r = new BufferedReader(stuff) will let you use BufferedReader-specific methods on r, which is usually ok. The times that it’s not ok you can cast the BufferedReader to Reader, or not use var.

    var is more general than your new() idea, as var can be used in statements not involving ‘new’.

    “my initial reaction is that using var everywhere demonstrates laziness by the programmer”

    I think it demonstrates that they don’t like writing repetitive code.

    Type inference makes your code easier to write and read, it stops there being a syntax penalty for introducing ‘explaining variables’, especially in conjunction with useful uses of generics, and it makes your code easier to refactor – less mentions of the type you are changing.

    In those cases that you’re unsure of the type of a variable, just change it from var to int and recompile, or, given decent tooling, hover over it and wait a few milliseconds.

  15. Adelle Hartley says:

    Florian Potschka wrote:
    > But on the other side you loose a lot of the readability and error-safety you get when explicitly stating the type.

    There are certainly cases where readability is lost, but there is no loss of error-safety – that’s kind-of the point of it: The variable is still of a specific (non-variant) type, just as though you had declared it as being that type. Even the OP mentions that you can’t assign it to to a value of another type. (I love Variants too, it’s one reason why my dynamic-typing-envy never escalated to full-blown dynamic-language-using).

  16. Bj says:

    I’ve had the same thoughts as you Richard. Using var everywhere is going to make the code less readable. To figure out what kinds of types you are dealing with you are going to have to navigate into methods or use intellisense. I have noted with skepticism that Resharper proposes to change all types to “var”.

  17. Jason P says:

    I think if one is using a statically typed language they should go nuclear and put types most places they can. var makes some refactorings just a little annoying, imho.

    BufferedReader br = new BufferedReader (new FileReader(name));

    but I’m using C# 3.0 so I might as well:

    var br = new BufferedReader (new FileReader(name));

    but I need to decide the type of br at runtime, so I do my normal cut and paste:

    var r;
    if(needBuffered)
    r = new BufferedReader (new FileReader(name));
    else
    r = new MagicalOtherReader (new FileReader(name));

    compile error! Now I have to think about what my common baseclass is. Thisis a pretty trivial example and it probably isn’t that annoying, but it’s something to consider. I always try to use the least specific type that has everything I need when declaring variables. That usually comes down to an interface.

    In the C++ world, though, the forthcoming auto keyword has a totally different use that I think is great. Declare any loop iterators as auto since the types for templated containers are long as hell.

  18. Troy Gilbert says:

    Static-typing with explicit types (as opposed to “var”) has the advantage of functioning as an assert, i.e. it allows the programmers to require a compatible type be returned from an expression. This doesn’t appear to be so much of an issue in the examples given, but would if they contained functions provided by a different (possibly third-party) module. In which case, if their interface returns code will fail silently (in some cases) or throw an error when you finally attempt to use that “var” according to the type you’re assuming it has.

    And that’s the real problem: “var” puts an unspoken assumption into the code. It doesn’t declare how a variable will be treated in the following lines of code. Yes, it makes the variable declaration more flexible, more robust to refactoring (for some scenarios), and the brevity is nice… but it fundamentally strips what could be (and usually is) useful information from the source code.

  19. Mark Lee Smith says:

    Whether or not Jeff got it wrong, you certainly haven’t got it right. Any 1st year CS student should be able to determine when it’s appropriate to use this feature, and when it isn’t. Why can’t professional programmers? It’s bleeding obvious.

  20. Mark Lee Smith says:

    I think most C# programmers would have been happier with optional-typing, as in Objective-C or Dylan, instead of the simple type-inference they got.

    Had C# provided a mechanism to declare a variable of no-type none of the examples above wouldn’t have posed any problem. C# would have cute dynamic features on-demand, like full duck-typing etc.

    Other than brevity I’m not sure that var adds value outside of the problem domain. It’d be interesting to see how ‘var’ handles collections of possibly-overlapping interface-types… or doesn’t.

  21. Weekly Link Post 47 « Rhonda Tipton’s WebLog says:

    [...] Richard Dingwall talks about the C# var keyword in his post C# 3.0

  22. Just Because You Can Doesn’t Mean You Should : An Experiment in Scotch says:

    [...] the conclusion that you should use var a lot more than you are so that your code is more concise. Richard Dingwall shows why Jeff has missed the boat on this one. Jeff has written in the past that any time you can [...]

  23. Cristian says:

    As others have noted, your article kind of sucks. I hate people like you who want to become popular by bashing other people. You could have made your statement (preferences) public without mentioning Jeff.

  24. Manav says:

    I think the title is sensationalist but the content of the articles are good. What kind of idiot would give an advice to not define all variables with var type. Think of a simple problem, if you define a variable as:

    var foo = myclass.getfoobar();

    This code has a subtle bug where if getfoobar’s signature changes and it returns a different type, you wouldn’t get a compiler error. Now think of a project of size 100000+ lines and you can see how hard it would make it for people to change the function signature.

    As the MSDN documentation itself mentions, the use of var should be avoided.

    It is an irony that a person with a website title “CodingHorror” gave an advice for horrible coding:).

  25. Manav says:

    * I meant*
    What kind of idiot would give an advice to [deleted not] define all variables with var type.

  26. Buu Nguyen says:

    >>Person p = new(“FirstName”, “LastName”);
    What if I don’t need the variable? For example I usually do this: new Thread(new ThreadStart(Loop));. How would I do that now if the right-hand-side type is eliminated?

    The rest of the post spots on. Completely agree about the use of base type when necessary and avoid ‘var’ if that hinders the code understanding.

    Mr. Atwood seems to have the tendency to repeat what others have said for many years as though he though of it in the first place. But most of these people (those before Jeff) really makes a mess over this “redundancy” thing to “sell” how coolness some dynamic languages are – so no need to consider their thoughts wholeheartedly though (and then wish C# becomes say, Ruby).

  27. Alex says:

    I tend to agree with this post. I see a psychological benefit to strong, unambiguous typing for more detailed code. I also see the real-world protections it affords as Manav (comment 24) and Troy (comment 18) illustrate.

    Then again I personally come from a history systems development, pushing bits around, so overuse of the var type feels dirty to me. I have a bias.

    – Alex

  28. Alex says:

    Oh, and I think the

    Foo f=new()

    is a pretty cool idea… Regarding Buu’s comment (#26)… it would have to be optional…

    Foo f=new()

    would be equivalent to

    Foo f=new Foo()

    A shortcut… analogous to i++ being equivalent to i=i+1

    – Alex

  29. average.joe says:

    yeah, i’m inclined to agree with richard

    just because you don’t want to write the type twice, that doesnt mean you should use some other feature, which is clearly designed for something else, to compensate

    myclass bob(“hello”,1);

    or

    myclass bob = new(“hello”,1);

    makes much more sense

  30. The var war is brewing - Derik Whittaker says:

    [...] post he talks about using var to remove redundancy.  However, in Richard Dingwall's posts he thinks that Jeff has it all wrong.  Well, I am here to tell the world that they are both [...]

  31. Kevin Berridge says:

    I definitely agree with you on this. Readability trumps write-ability in all but the most extreme cases in my book.

    It’s considerably easier to read the left hand side of the “A thing = new A()” statement than the right hand side. This is because the left hand side always starts in the same column and therefore can be easily scanned. If you start seeing “var thing = …” you have to stop and start scanning to the right to figure out what the type will be. This is an example of one of those small efforts that adds up over time that Jeff Atwood posted about yesterday.

  32. I don't get var - Code Heaven says:

    [...] than the second variation. As IanG noted in 2005, Var Isn't Object, and more recently, Richard Dingwall exposed the differences between it and genuine variants — it provides full strong-typing, and the [...]

  33. Ben Amada says:

    For any good sized project, I would much rather variables be declared with an explicit type. Code is written once. The same code is read many more times for maintenance and subsequent modifications. More time will be lost trying to refamiliarize yourself with the intended types each time you review code containing a large number of inferred types than the time saved not explicitly stating the type in the first place.

    As Manav stated (in post # 24 above), what happens when a function’s return type changes? The change may or may not cause undesirable effects in code that is calling the function. But why take the chance? I’d also like to avoid the possibility of a future version of the compiler inferring the type of a variable differently. As stated by others, in VS, you can hover over a “var” declared variable to see its type via intellisense. There are times, however, when I am looking at code outside of VS and intellisense is not available.

  34. Tony says:

    My fellow developers and I have had extensive conversations on this subject and have for the most part agreed to disagree. There are points to both sides of the argument here.

    Explicitly typing
    1) in cases of initialization by a method or function explicitly typing makes the code more clear.
    2) When in need of a variable that you can’t initialize right away (although this should be rare).

    Implicitly typing
    1) when initializing a variable in c# the part on the right hand side of the = is more important than what is on the left. example

    List names = new List {“Tony”, “Bob”, “Mike”, “Phil”};

    Developers for typing say that adding var makes it less clear here because it doesn’t tell them what “names” is right away. To which I respond that is the point. You need to look past the left declaration and focus on the right which has more going on than just declaring an empty list.

    2) using var with initialized variables does remove the redundancy and make code easier to read.

  35. Max says:

    Great post

  36. Rick says:

    Nice post and I understand the debate, but I don’t agree with the poster.

    First: declaring lots of (local) variables is a sign of bad coding practices, in my opinion. Second: having to know the type of a variable to be able to understand your code is a sign of bad naming practices, in my opinion.

    And to those that say that this will generate more run-time errors: please read up on the subject again. There is no dynamic typing going on when using var.

    So to me, it seems like a bad idea to do both, using a lot of explicit type declarations OR var’s – but if you must, use var, as it is shorter and the type information is right at your mouse pointer if you really do need it.

  37. Nicholas Paldino says:

    Sorry for the late, LATE response to this, but I wanted to say thank you for quoting me.

    @Jonathan Allen: I should have elaborated, but what I meant by that was this is something that should be included in the language. You are absolutely right that it can’t be done now. I have recommended it to Mads at MS though, but I don’t know if it gained any traction.

    @Buu Nguyen: My recommendation (if it was implemented) does not make using the type on the right-hand side an error. You could still use it, just the same as you would before (and it would have to be that way, since there would be all that legacy code to support).

  38. Nicholas Paldino says:

    @Richard:

    If you want to support this in the language, then vote for the suggestion at the Microsoft Connect site:

    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=388649

  39. Rickey Ward says:

    I agree with this article, I myself even when using non strict languages, for example as in flash, I always strict data type my variables. I would like for those languages to give me an option of using data types as a declaration, so instead of string name = “Rick”; im stuck with var name:String = “Rick”; strict is the way to go. Its easier to read, and understand. its easy to loose track of a complicated application with hundreds of variables, I look for those data types to help me remember what my variables are intended to help me do.

    and also, a short hand method would be nice, but i don’t mind the typing, especially with VS2k8 all you have to do is type the first letter of the type after typing new and then hit enter and its auto completed.

    Every programmer has their own preference.
    happy coding

  40. Implicitly typed variables in C# using var « This one goes to 11 says:

    [...] inspiration to chime in on this topic came from this blog post.

  41. Nick says:

    >”`var` says “The type here is not important; Whatever type that expression happens to be, will do.””

    Haha! There’s proof right there that var can cause LAZINESS!

    However, removing/restricting the use of var in C# isn’t going to help the unfortunate who already abuse it. Syntax isn’t going to fix laziness, they’ll just find another language…

  42. RJ says:

    var should be removed. I also don’t see how anon types are required.

    I will admit, I do not know linq nor would I use such a blasphemous syntax. Maybe if I was younger and less bitter. To me that syntax is like like eating puke that I just puked. I hate to think what the junior devs are going to do with this crap and the resulting code.

Leave a reply

We love to hear your views.