Stop Using var (C#)!
I just picked up Andrew Troelsen and Philip Japikse’s Pro C# 7 Eighth Edition to catch up on some of the more recent language and platform changes (being stuck in SharePoint 2010 for 8 years will do that to you!).
I remember picking up the second edition and reading that thing front-to-back in my early days when I was just starting out. (At that time, I had already completed several .NET projects but I felt embarrassed after failing an interview and I was determined to make sure I understood the framework to it’s practical depths). This is a book that I still highly recommend to all developers I work with; I’ve had just about every junior developer I’ve hired — and even some senior ones — to read key pieces of this book.
I’m already loving this revision. Troelsen calls out one of my biggest peer pet peeves, the excessive usage of var :
…using var to declare local variables simply for the sake of doing so brings little to the table. Doing so can be confusing to others reading your code because it becomes harder to quickly determine the underlying data type and, therefore, more difficult to understand the overall functionality of the variable.
In fact, it could be argued that the only time you would make use of the var keyword is when defining data returned from a LINQ query. Remember, if you know you need and int, just declare an int! Overuse of implicit typing (via the var keyword) is considered by most developers to be poor style in production code.
(Troelsen and Japiske 97-98)
This is one of the first settings in ReSharper I ask devs to switch to ensure that we always have explicit types because it just makes it easier to read.
My personal guidelines have been drawn from McConnell’s Code Complete where he writes:
The smaller part of the job of programming is writing a program so that the computer can read it; the larger part is writing it so that other humans can read it. Let [the reader] use their brain cells to understand the larger question of how your code works rather than the syntactic details of a specific expression. You write readable code because it helps other people to read your code.
I encourage more of my peers to preach the gospel!
Wouldn’t the value of explicit typing be less relevant if you make sure you are using proper naming strategies for your methods and variables? I’m not talking about Hungarian notation, but in reading and understanding the code, does it generally really matters if someAmount is an int or a double, until you’d do arithmetic on it and it then, if not earlier, becomes obvious what specific type of amount it is?
That is, if you name your variables properly, wouldn’t you have narrowed the possible type enough so that it doesn’t really matter what exact type it is in term of understanding the code?
Do your references point to any hard data on the readability effects here, or is this just personal opinions as usual?
With simple value types, the distinction is not that great. But with object types in your domain — especially if the domain is large — it helps to have the explicit type in place for readability and reduce the amount of inference required from the user.
Do I have any hard data to back that up? Nah, and I’m too lazy to go look 😀
But my personal preference is for full explicitness; it doesn’t hurt and the compiler doesn’t care. With intellisense and ReSharper, there’s virtually no difference in keystrokes. However, it sure does make it easier to read IMO.
I quite disagree on this one. Writing duplicated code like List myVar = new List(); is just a waste of screen space and adds to the confusion of what is important. VS will easily tell you the type of your variables should you need it. It is most of the time implicit or too complex to be useful written down (LINQ). The int example is fine but I don’t think it extends much further and in particular it seems to me it doesn’t apply well to containers. Less code is less things to process for humans, the criteria should be: does it add useful information or is it redundant.
A big part of readable code is consistency. So while something like List myVar = new List(); seems innocuous, when one has a large domain space with hundreds of classes and multitudes of related classes, it can be very helpful to know the underlying type to have some additional context clues as to what the code is doing.
I think it also helps with navigating code in a large domain, especially with ReSharper in Visual Studio — or any other modern editor — because you can start typing the CTRL+SHIFT+N and start typing the class name since you can see the class name explicitly (assuming your name your files after your classes).
So using var for System types and explicit declarations for non System types may work for you, but I find that inconsistency jarring so it’s easier to just keep everything explicit (ReSharper also has simple refactoring rules for this as well).
As McConnell writes in Code Complete, code has far higher information density than prose so having contextual clues will help the reader more easily digest that density. When I write code, I’m always thinking about the next reader and how to make it easier for them to digest it, even if they are new to the codebase. It’s the reason for having good naming schemes and conventions and — to me — using explicit type names is just an extension of that: making it more consumable with context clues.
I completely agree on consistency, I even think within reason it is more important than the actual convention used. However by force of habit I tend to react to ‘this convention should always be like this’. Because while the first person might have thought about it, by the time you get to the third one it’s become a rule and then it’s applied without thought. It reminds me a little of the C++ type postscripts, _m, _i, _p etc. This was done in times of simpler IDEs where it was harder to infer types. I think it has lost it’s reason to be in modern IDEs and .NET however you’ll find devs who still follow this rule.
So in this regard, my questin becomes what does the reader need to do, is he trying to sue the function and wants to understand what it does, is it a QA proof checking, a debugger, an auditor etc? Are you readers going to be mostly juniors or seniors, c++ or python background? Is it open source or private? I would adapt my ways (slightly) to ensure communication through my code would be optimized for the public. Many times we know exactly who will read our code and in what context(s). For example if parts of the code are heavy on algorithm I’d probably try to enhance the comprehension of the algo logic even at the expense of the readability of some more minor details. If it’s a critical security piece of code I might pay more attention to a careful line by line clarity. I personally don’t use ReSharper as I tend to think it makes devs lazy, as you mention in another article it allows them to use magic they don’t understand. That is also why I think a paper coding interview exercise however simple is always telling.
> Many times we know exactly who will read our code and in what context(s)
I don’t think it’s that simple man; I’ve worked with customers who have .NET code that is over a decade old. Where the original authors are long gone and maintenance has to picked up by the third, fourth, or tenth team to touch that code. At my first job out of college, I wrote a custom job posting management system and years later, I was checking their website and it was still in use. I’ve also transitioned products to offshore teams where English was not their first language. So I think that has shaped my own preferences to be as explicit as possible so that no matter the reader, no matter their skill level, the code is approachable.
> I personally don’t use ReSharper as I tend to think it makes devs lazy, as you mention in another article it allows them to use magic they don’t understand
I don’t know if this is the case with ReSharper. The main benefits of ReSharper for me are:
ReSharper has some functionality for templates (which I think is good for consistency), but the primary reason *I* use it is for faster navigation of code.
> That is also why I think a paper coding interview exercise however simple is always telling.
I personally do not use this approach because I think it would not be fair. I’ve gone through interviews where I’ve had to write code in paper and pencil and passed, but the experience was sub-optimal (try writing a simple bubble sort on paper — it ends up being a formatting mess). I used to do it via WebEx and allowed candidates full remote access to my local VS.
I’ve switched to using https://dotnetfiddle.net and https://jsfiddle.net; both are great tools that are great assets in a technical assessment. I don’t mind that with dotnetfiddle that it gives compile errors and contextual highlighting; the focus of a technical interview — even with the most junior candidates — is whether they can think problems through. Syntax can be learned quickly, but critical and creative thinking are hard to teach!
I’ve hired developers that failed every item in my technical assessment because they had the right personality and internal drive. I’ve hired developers who didn’t know C# but showed an innate desire to learn, improve, and contribute (and handed them Troelsen’s book!) who have then moved on to senior and principal roles in other companies.
If you focus too much on the nuts and bolts, you’ll miss all of the critical and creative thinkers 🙂