Implicit Typing: To var or not to var?
Since the beginning of time, religious wars have been fought over differences in religion and beliefs. I think this is one such war. C# 3.0 introduced the concept of implicit typing back in 2007 with the keyword var. Since then, you are bound to find people vehemently opposed (and disgusted) by the concept, and others that embrace it to the point of no return. I’m going to try to take an impartial look of implicit typing here (but you may conclude that I have failed).
First off, the facts. MSDN’s “Implicitly Typed Local Variables” has a very concise explanation, but let’s try to distill it even further.
- Local variables (and only local variables) can be declared with an inferred “type” of var instead of an explicit type.
- The var keyword tells the compiler to infer the type of the variable based on the right hand side of the initialization statement. (ie. You must be in a statement that declares and initializes the local variable to use var; there is no: var x;)
- In many cases, the use of var is optional and is syntactic convenience.
- var is not optional when the variable is initialized with an anonymous type.
- var may be useful with query expressions where the exact constructed type of the query variable is difficult to determine.
- var can be useful when the specific type of the variable is tedious to type on the keyboard, or is obvious, or does not add to the readability of the code.
- var does have the potential to make your code more difficult to understand for other developers.
When a member of my team, CS, started using the keyword var, I despised it. Though the concept is so simple, it’s actually a fairly large paradigm shift. I thought it made code less readable, and also broke my IDE’s autocompletion feature. At first he suggested that we only use it for LINQ queries, initializations with constructors, and casting statements. Trying to keep an open mind, I gave it a shot, and it didn’t take long before I found out that I actually liked it. Code was looking nicer, cleaner, and simpler. Talk about heading over to the dark side!
Dictionary<string, List<Item>> dictionary = new Dictionary<string, List<Item>>();
vs.
var dictionary = new Dictionary<string, List<Item>>();
Which looks better? (In case it’s not obvious, I think the latter is leaps and bounds better.) Or:
DateTime dateTime = (DateTime)eventArgs;
vs.
var dateTime = (DateTime)eventArgs;
At this point though, CS had moved on to using it practically everywhere (except for value types)! What the heck!? It is a slippery slope. I acknowledge that this is probably not as obvious:
foreach (var kvp in this.dictionary) { … }
vs.
foreach (KeyValuePair<string, List<Item>> kvp in this.dictionary) { … }
… but it’s actually way more readable. Anyway, you can probably tell that I slid down that slippery slope. Now I, too, use it when I can (except for value types, though I would not be surprised before I start using it literally everywhere). There has been backlash though, against this usage. Why?
By far the largest argument against the usage of var that I’ve seen is that it’s not always clear from looking at the declaration of the variable what the type really is (though this is certainly not true in the previous two examples):
Con: I can’t tell what the type is.
Pro: If you use VS and hover over the variable, it tells you what the type is.
Con: I don’t use VS.
Pro: …
Con: I can’t tell what the type is in Notepad.
Pro: O__o’
Actually I don’t use VS either (I use a combination of SourceInsight and vim, neither of which grok var), yet I like var a lot. Why? At the end of the day, I think that argument comes down to the naming of local variables. When you look at a variable being used in code, you are usually looking at its usage instead of its declaration. I find that naming the variable with a descriptive name often helps much more than the declaration statement far above, because you don’t need to search for the declaration at all! For instance:
stringBuilder.Append(“foo”);
vs.
s.Append(“foo”);
What the heck is “s”? (Yes, sometimes I will shorten it to “sb” too.) It has been brought up many times before that the benefit of “better naming for local variables” “really means it compels developers to use longer Hungarian style variable names.” –Carnage4Life. Personally I think that is a good thing to follow in general; I don’t find it adding to the “noise” in the code.
One other benefit of var that I don’t see purported too often is that when you change a type, property, or return type of a method, you don’t have to go change every usage of that type as well. Take, for instance:
var fraction = new { Numerator = 9, Divisor = 11 };
var value = fraction.Numerator / fraction.Divisor;
The second variable, value, would be implicitly typed to be an ‘int’ in this scenario. But if I were to change ‘Numerator’ to 9.0 instead of 9, value would be typed as a float, without me having to change that line. Obviously this is somewhat of a contrived scenario, but one could easily imagine changing a property in a class (or a return type of a method) and have all the callers of that property to “just work.”
I can’t imagine that the debate to var or not to var will ever end, but I for one, love it. After having used it dutifully for several months, I cringe at the thought of typing out types—it’s so 20th century! I’m completely hooked.
Let’s end off with a comment thread from ReSharper:
C: Variable type declaration is not equal to variable instantiation.
P: If this were true, the compiler would be unable to infer the type.
C: I’ve fought far to many battles in classic ASP and vbscript where the type I thought was going into the variable wasn’t the type I ended up with.
P: Comparing a dynamic language with a strongly-typed one isn’t a great way to develop best practices. Yet again, I have to ask why people are scrolling to the point of variable declaration to determine the type, rather than just hovering over the variable.
C: That’s supported in Visual Studio only. What if you’re reading code on paper, on a web page, pdf or plain text editor?
P: If that’s a primary design concern, I worry about your development process.
C: I guess you’ve never heard of code reviews.
P: Sure, we do them too, just not on stone tablets.
It’s certainly interesting how something so seemingly trivial could incite such passionate debates among people.
The argument that you can just reinvent hungarian notation just so you keep using var everywhere is one of the signs you’ve gone off the var deep end.
要照顧身體歐~保重—-幫忙踩個人氣 http://dimi.com.tw
Bravo!!. Soy el responsable de un equipo de desarrollo y estoy en esta misma situacion. To VAR or not to VAR? La cuestion es simple, no acepto el abuso de VAR sobre todo cuando me hace mas dificil la lectura del codigo. Aqui no has puesto el ejemplo que mas me molesta: var xx = objeto.GetXX();DE QUE TIPO ES xx????Lineas como esa me obligan a ubicar el mouse encima para saber el tipo de Retorno de GetXX() y eso me hace perder mucho tiempo, maxime cuando una de mis tareas es revisar el codigo del equipo. Tambien estoy en desacuerdo con el abuso de var a = 2;Por favor señores! es muy simple escribir: int a = 2; No creo que este de acuerdo en que el compilador determine el tipo por mi, y menos un tipo de dato simple o primitivo, como le llameis.Tenia entre mis tareas escribir en mi blog casi lo mismo que aqui ya esta escrito, aunque con un espiritu bien critico acerca de estas 2 malas parcticas que he mencionado. Gracias, ahora me limitare a traducir este al español y referenciarlo. http://deisbel.blogspot.comTraduccion al Ingles con Google Translator————————————————–I’m responsible for a development team and am in this same situation. To VAR to VAR or not? The question is simple, do not accept abuse VAR especially when I make more difficult the code reading.Here you have not set the example that bother me:var xx = objeto.GetXX ();Xx what kind it is??Lines like that make me place the mouse over to see the kind of Return GetXX () and that makes me lose a lot of time, especially when one of my tasks is to review the code of the team.Also I disagree with the abuse ofvar a = 2;Gentlemen Please! is very simple to write: int a = 2; do not think this agreement that the compiler determines the type for me, let alone a simple data type or primitive, as you must call.Between my work had to write in my blog almost as much as is written here, but with a good critical mind about these 2 bad parcticas I mentioned. Thanks, now I will just translate this to Spanish and reference it.http://deisbel.blogspot.com