Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Got var?

I had a couple of interesting discussions at the recent MVP summit around my preference to using the var keyword in my recent set of codebases.

I argued that people who are already in the habit of expressively naming their variables are going to be much more open to dropping the extra "noise" of specifying the type on both sides of the variable declaration.

Having been exposed to dynamic languages (Ruby) has definitely altered my perspective with regards to considering this:

IList<Customer> listOfCustomers = new List<Customer>()

Much more noisy than this:

var listOfCustomers = new List<Customer>()

As I strive toward more readable, intent revealing code, I find myself looking at the intent behind the usage of the variable coupled with a meaningful name, vs the actual type. In reality, I find the the argument to not use var is a moot point in a static environment that provides you with all the information you need once you hit the "."

How do you var?

Develop With Passion!!

This entry was posted in C#. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

33 Responses to Got var?

  1. Bill Barnes says:

    Does all this collapse down to the usual argument between static and dynamic typing? If you are a fan of Ruby-like duck typing (“All I care about is that I can call a method called Fire()”) then var is your friend. if you are suspicious of such devil-may-care frivolity then you probably won’t.

    The fact that we have both static and dynamic languages (popular ones) is evidence that there is no right answer. The fact that Mr. Strong Typing himself, Anders, put this feature in his baby is evidence that even he sees both sides of things.

    For my part I am proud to be lazy. Save me typing? Cut down on characters or even lines of code? I’m in, damned the torpedoes, full speed ahead.

  2. I’ve got a slightly different take on it. I really get bugged when I find myself using var “sometimes” because it seems like I don’t really have any solid rules for doing so. I’d like to use it everywhere, but I can’t do this:

    var number;
    if ( Int32.TryParse(“1″, out number) {

    }

    (yeah I know I could waste a variable initialization but again, I’m too picky and that would bug me.)

    So for me, I’m gonna have to figure out a compromise probably somewhere between “use it only when calling a constructor” and “only use it for anonymous types”.

  3. There are issues with overflow.
    For example you start off with this:

    var amount = 2147483648;
    amount = Int32.MaxValue;
    //….
    amount = 5;
    //….
    amount += Int32.MaxValue;
    Console.WriteLine(amount);

    The result is 2147483652

    Then someone changes the first line (or even worse a method returns a different value) to this:

    var amount = 2;

    and now the result is -2147483644

    Woops!

  4. Mark Sowul says:

    All of the pro-“var everywhere” arguments are great in theory.

    However, once you come back to code you’ve forgotten, you’ll probably thank yourself for using var sparingly. Moreover, bugs exist – sometimes you don’t write what you thought you were writing. The more you can do to ensure that you are doing what you thought you were, the better (to a point). As per my earlier comment: I want an explicit declaration somewhere in the method. It makes it more obvious what is being done later on when you revisit it, and the “redundancy” provides less chance to screw up.

    “Therefore you can’t rely on getting a compile error at every call site in the face of this kind of code change. ”

    So? Just because it’s not a 100% guarantee doesn’t mean it’s a useless precaution.

  5. Hi David,

    I’m not assuming they are – you’re assuming they aren’t. :-)

    Whether you think it’s bad practice or not (note that it’s fundamental to how composability in LINQ works), the point is you *can’t* assume that calling code doesn’t do this. Therefore you can’t rely on getting a compile error at every call site in the face of this kind of code change.

    So this argument (which is the only concrete one I’ve seen) just doesn’t really wash.

    If it really matters that a variable is a certain concrete type then you should specify it. But it hardly ever does. In general this depends on the level of abstraction of the code you are writing. C# 3.0 raises the abstraction level considerably – the new features are all in some way about letting you say “what” instead of “how”, and var helps us to say “what”.

    Many people have a vague feeling of uneasiness about var which we should try to ease by unpicking concerns and argument like this.

    Pete.

  6. David Nelson says:

    @Pete,

    You are assuming that calls are regularly chained together as in your example. Since chaining dependencies is generally considered an anti-pattern and bad practice, I was not considering that possibility in my argument.

  7. It seems to me that this “subtle bugs” worry is the underlying assumption in this debate.

    I have yet to see an example provided to support it.

    One worry seems to be, “If I use ‘var’, the return type of a method could change. The new code shouldn’t compile, but it still does, because I used var”.

    We could imagine completely changing the contract of the method GetKalashnikov() to return a Gun instead of an Employee. The worry seems to be that if you now call its method Fire() it will do something completely different, and using ‘var’ won’t alert you to this.

    But this was always possible!

    Instead of

    Employee e = GetKalashnikov;
    e.Fire();

    calling code could look like this:

    GetKalashnikov().Fire();

    The assumption seems to be that you can rely on the existence of type annotations to ensure that a particular method is being bound to.

    You can’t, and never have!

    You can’t rely on a call site to specify the return type it is expecting.

    If you change a method’s return type *and* its contract and are worried about what the call sites are doing, the only thing you can do is to visit all those call sites and check the code…!

    This has always been the case, and isn’t a problem avoiding ‘var’ will fix!

  8. MoDo says:

    I always like to think of things in cost. The ‘var’ keyword is very new to me so my comments might not carry much weight and I reserve the right to change my mind, but…

    I can see that using the ‘var’ keyword would allow bizarre bugs to be introduced when code changes in a remote and seemingly unrelated function. However, it can be frustrating when you do change the return type of a function from one type to another and have to chase around the code to make everywhere reference the new type.

    So the question is does the cost of chasing up bugs outweigh the cost of chasing the strongly named type around the code. Different situations probably require different approaches, but in most of my day to day work I can definitely see the benefit in using ‘var’.

  9. Bob the Builder says:

    It’s amazing how negative people are about this great feature.

    Just use the type inference, it’s part of the language.

    Most of the time you really don’t need to know the type of an expression.

    That “listOfCustomers” has been trumpted and accepted by everyone on this thread as example of “descriptive variable naming” is ridiculous – we only just got rid of the Hungarian “lstCustomer” madness.

    This is the same thing. We don’t need type names in our variables, and we don’t need them in our code at all most of the time.

    Here’s my advice:

    Use “var” everywhere you can, expect for assigning to primitive types with language aliases such as string and int where it doesn’t really give you more clarity or flexibility.

    Type inferencing makes the language more elegant, modern, flexible and easier to read.

    Why be happy to use it all over the place in query comprehensions and lamda expressions but spend your time hand-wringing about it in other parts of your code?

    Join the new century!

  10. @Davied Nelson: “To those claiming that var was introduced because “LINQ expressions can return some unwiedly types” or “you may not know before hand what type a query will produce”:

    var was introduced for one reason: anonymous types.”

    And thus you may not know before hand what type a query will produce. Not being part of the team that developed LINQ I can’t say for sure but to me it seems that anonymous types was a big but not the sole reason for the var keyword. If it was why would they not have just used an “anonymous”-keyword used only for anonymous types? Clearly the var keyword has great benefits when starting out to write a query. I’m also quite certain that the the team realized that type inference was a general benefit for the language (just as it is in F#) and included it not only for the benefit of anonymous types.

  11. mglaze says:

    I think the examples being used here are over-simplifying the problem and not really portraying how complex this can be in the real world.

    Instead of the trivial-looking example GetCustomers(), how about if we have something like:

    var instrument = LoadAppropriateInstrument(fields, dateRange, loadParameters);

    This is derived from a real example from some code I’m working on. I show it to raise a few points:

    1. When we discuss collections, we are simplifying things way too much – of course you would say that you don’t care whether it’s a List or an Array – collections generally have a lot of similar methods. So let’s discuss something a bit less templatized and trivial, such as our own custom business objects.

    2. The “Load” instead of just “Get” implies that this is doing something non-trivial, such as pulling this data from a database or remote source; not sure if everyone would consider that relevant, but for some reason I do.

    3. What if the return type of this function is IPersistableInstrument, and this isn’t exactly obvious to anyone looking at the code because that is just one interface in the middle of a hierarchy of possible interfaces and objects. Below that we may have things like IInstrument, and above we may have IPriceableInstrument. Well, perhaps this point could actually be an argument for var, rather than against. Not sure whether the hidden complexity outweighs the improved clarity.

    4. In the future we may extend this object hierarchy and the return type of this function may change. Again, i’ve heard this used as an argument both ways – but personally I would probably prefer to have explicit compiler errors at that point to force me to go and look at all of the breaking points in the code, rather than hiding a potentially disastrous assumption that becomes a bug.

    In general, I tend to agree with those that say the best usage of var is to limit it to only cases where we are explicitly showing the return type (i.e. mostly constructors), and to avoid it in all cases where the return type is not clear (i.e. everything but constructors). To bring up an example of a case that might fall in between these two, how about:

    var customer = BusinessObjectFactory.CreateNew();

    It’s not a constructor, but the pattern serves the same purpose, and using templates we’ve also made the return type explicit enough to anyone who understands what the pattern is for.

    In the end, I think I lean more towards the point about var having been introduced specifically to address the problem in LINQ of anonymous types. If that is the case, then wouldn’t it be better to say that we should limit it’s usage exclusively to anonymous types?

    An interesting debate, to be sure.

  12. int19h says:

    Bear in mind that if you ever use lambdas with type inference, or LINQ constructs, you are effectively using ‘var’. There is no semantic difference between:

    GetList().Where(o => o.Name);

    and:

    foreach (var o in GetList())
    Console.WriteLine(o.Name);

    and:

    var list = GetList();
    var o = list[0];

    Both are equally “obfuscated” and prone to quiet breakage if the return type of GetList changes; but, well, you can always break things with explicit typing, too (ah, the wonders of “new” specifier on class members…).

    In reality, if you follow good programming practices with regard to naming, and your methods fit on one editor page, using type inference should be no problem – you should be immediately able to deduce type from method names and the way the variable used, to the extent that you really care (i.e. if you see variable used in “foreach”, you know it’s IEnumerable, and the fact that it might in fact be deduced to List is rather irrelevant).

  13. David Nelson says:

    To those claiming that var was introduced because “LINQ expressions can return some unwiedly types” or “you may not know before hand what type a query will produce”:

    var was introduced for one reason: anonymous types. The compiler can create types from a query expression that have no definitive name, and therefore you cannot declare a variable to hold them using traditional syntax. It has nothing to do with the types being unknown (unless “anonymous” is what you mean by unknown) or too complex.

    As to whether var should be used in situations not involving anonymous types, I tend to agree that it is ok when the type is explicitly stated on the same line (this is basically the same as VB’s “New” syntax). But when assigning the result of a method call or other indirect expression, I don’t think its a good idea. You can make all the arguments you want about the IDE providing type information, but I agree with Mark (“if GetListOfItems changes, so does your code without you realizing it”) and Simon (“Thou shall not obfuscate” wins over “Thou shall be succinct”; especially during code reviews).

  14. Frank Bakker says:

    Consider the following fragment

    GetCustomers().Count;

    In the case the result of GetCustomers is not assigned to a local variable at all.
    You don’t get any more implicit than that. Still it is very clear what is going on, and few people would have a problem with this. This is not very diffrent than:

    var customers = GetCustomers();
    ..
    customers.Count;

    We still don’t know the return type of GetCustomers and we still don’t care. The local variable customers is just as explaining as the method name GetCustomers()

    As long as you stick to the rule that a Method body fits on a single screen (or printed page for that matter) and you give your variable a clear name I see no problem with using var. The type of a variable is just not as important as many people think, that’s also why we stoped using hungarian (most of us did).

  15. IList listOfCustomers = new List()
    var listOfCustomers = new List
    ()

    These two lines doesn’t do the same thing, in the second line the listOfCustomers would be a List rather than an IList so the cases can’t be compared. Also, to type a local variable by its interface seems wrong to me, there’s no real benefit unless the implementation has made explicit interface implementation on some member that you want to access and has hidden it.

    In my opinion the var keyword makes perfect sense where it’s obvious what the assignment will produce. Ironically it was created for the opposite situation, to help support LINQ where you may not know before hand what type a query will produce.

  16. Ryan C Smith says:

    I think the difference is that with LINQ it’s expected that the resultant type will be wild and unpredictable.

    However with a defined method it should be pretty concrete as to what’s coming back from it and if that’s the case then explicitly typing it will make it easier to read if you end up reviewing the code from outside the IDE.

    Then it comes to writing code for the IDE and writing code for some other medium…I’d rather have one way that made it easy to read in both mediums.

    But ultimately for me it’s too early to tell…I’ll let you know in a year or so when I have to come back to the code I’m writing today and we’ll see if it really does bite me in the rear or not.

  17. The opposition to:
    var listOfCustomers = GetCustomers()

    is interesting, considering that is the exact usage pattern that drove the introduction of var. LINQ expressions can return some unwiedly types, so its easier to just refer to them using var.
    It turns out that it the specific type of an object is a lot less important than what you can do with the object.

  18. Ryan C Smith says:

    basically either:

    IList listOfCustomers = GetCustomers()

    or

    var listOfCustomers = new List()

    but never:

    var listOfCustomers = GetCustomers()

    at least IMNSHO

  19. Ryan C Smith says:

    I’m in agreement with Kevin.

    Same line only…it makes reading code in blogs, books much more challenging.

    Somewhere on that line I’m reading should be an explicit declaration.

  20. Kevin Dente says:

    +1 for using var only when the type is otherwise specified on the same line. var map = new Dictionary() is fine by me, var map = GetMap() is not.

  21. Dave T says:

    I know at runtime it makes no difference – However your IDE will be faster if you do not do var too often. I know this because I had a classes that were using it extensively. Boy was it getting slow. Flipped everything and was quite snappy again. Maybe MS can explain why this is.

  22. Mark Sowul says:

    I agree with Simon; I don’t mind var in cases like

    var listOfItems = new List();

    but do not want to see things like

    var listOfItems = GetListOfItems();

    because 1) it’s unclear without looking at the signature for GetListOfItems(); and 2) if GetListOfItems changes, so does your code without you realizing it.

  23. wekempf says:

    JV,

    It’s not legal to say:

    var listOfItems;

    The compiler will not compile that line of code.

  24. Pablo says:

    Not to sound like a troll JV but your example code isn’t legal as you cannot use var in the manner you have presented. Next time how about using a feature first before writing about it. Just a tip.

  25. JV says:

    Inside the IDE there isn’t really an issue with this, as long as you use proper naming (Which doesn’t happen in a lot of cases). However a lot of source code is also viewed outside of the IDE and then you got an problem when using “var”.

    Also declarations as:

    var listOfItems;

    // do other stuff

    listOfItems = new List();

    will not make things more clear. It’s debatable if this is good code (Another discussion), but this happens a lot. And when using “var” this will obfuscate everything a lot more..

  26. Jon Skeet says:

    Eric Lippert made a great comment about var while reviewing my book. I’ve saved the comment for posterity:
    http://csharpindepth.com/ViewNote.aspx?NoteID=61

  27. Agreed, perfect example of less is more.

  28. Kyle Baley says:

    I’ve become a fan of it on the project I’m working on which has a team of one.

    With respect to Simon’s example, JP does imply that you should be in the habit of expressively naming variables. With that in mind:

    var listOfItems = GetItems( );

    looks fine to me.

    Even if it didn’t, I don’t know if I care so much about its type. I’m concerned more with what I’m doing with that listOfItems once I have it. If I see things like .Sort and .Find being called on it, what do I care if it’s a List or, say, my own implementation?

  29. First, Dave, you are the only one talking about “saving typing”, so the lazy remark is unrelated to this post.
    As the post says, its about reducing noise and promoting intention revealing code.

    I’m curious about the “code printout” argument.
    How often do you print out your code on paper?
    When you do, how important is it that a reader know the type of the variable?

  30. Dave says:

    Using “.” and mouseovers, to figure out your variable type is all well and good when you are in the IDE but what happens if your print your code? Var makes it a lot harder to figigure out the type especially in Simon’s example. Var is one of the things that makes Javascript a nightmare to work with (I know that you can’t dynamically change the type of a variable in C# like you can in Javascript but…..). My opinion is that it makes the code less readable (espesially printed) and if the only reason to use var is to save typing then that is just being lazy. Just my thoughts on the subject.

  31. Mark Rainey says:

    If I am working on someone else’s code, which most of us spend a lot of time doing, I would rather have the IList definition than the var defintion. I don’t want to have to stop all the time to work out the type of a variable defined with var.

  32. Ray says:

    While the idea behind var looks tempting I am strongly against using it. The above example by Simon explains it pretty well.

  33. Simon says:

    I think your example doesn’t really cover all the cases. Here is another one.

    This
    IList items1 = GetItems();
    compared to this
    var items2 = GetItems();

    I have not made a decision about “to var or not to var” but in the above case it seems “Thou shall not obfuscate” wins over “Thou shall be succinct”.

    Perhaps the rule should be something like “Use var when doing construction”????

Leave a Reply