OK, on a previous post I had a little bit of code with a ?var? statement in it. Actually, there were a few other items in there, couple of lambdas, lots of nested ?if?s, etc. There was a lot of good hand wrangling on how performant the Lambda ?Where? function is. According to the comments, not very performant for very large datasets. I don?t have a problem with that.
But at some point one of the commentors noticed that the var statement was just as fast as the explicitly called out type. Let me spell something out real quick: Once compiled, there is no difference between var and explicit types. ?var? is a language sort-cut, asking the compiler to figure out the type and inject it. This is not a runtime feature ? ?var? is a compile time feature.
Now, how often do I use var in my code? All the time. I use it practically everywhere. Think of it as a refactoring helper. Sometime I have to change a method from returning a IList to an IEnumerable. If I use a var and a foreach then none of the rest of my code has to change. That, to me is flexible code.
I could make my code more performant by replacing the foreach loops with for loops ? but I?ll keep the var?s thank-you-very-much. But most of the time I am not dealing with enough data to make that worth it. Most of the time I?m working with data to get displayed on web and mobile user interfaces. In those cases, limiting the amount of data I need to process, and then display, is of upmost importance. If I?m doing a file import (rare, but it does happen), then I switch to the other techniques.
Now, why bother? Why not always use the fastest method all the time? Because I find the foreach with ?var?s easier to read, more flexable code, and more refactoring friendly. For the vast majority of my code, that matters a lot more than eking out every last bit of performance.
@chris: I hear this argument about for vs foreach all the time. Interestingly enough: the foreach appears to be just like var in your example. It’s a language shortcut. If you write the foreach and examine the compiled code with reflector, you’ll see that it turns into a for loop.
That said, even if it wasnt, I’d prefer the readability over performant code… choosing to optimize the code only when a profile has told me that it is necessary. When optimizing prematurely, you’re virtually guaranteed to be optimizing the wrong thing.
@matt, there are some differences between for and foreach. To use foreach the data must implement IEnumerable, and you are iterating thru the data via the IEnumerable interface behind the scenes. While for loop uses the indexer property. There is a small amount of overhead when using the Enumerator. Actually, if you dissasemble the for loop into some languages, it actual comes out as a while loop instead of a for (delphi).
Wow… I attended a book club we hold in Cedar Rapids tonight and we had this exact same conversation (almost verbatim). I pointed out that it helps when you refactor, but until our conversation I didn’t realize the “zero-difference” in performance. It’s actually quite obvious once you figure it out or somebody explains it like you did.
1 for ALWAYS using var 🙂
“Because I find the foreach with ‘var’s easier to read, more flexable code, and more refactoring friendly. For the vast majority of my code, that matters a lot more than eking out every last bit of performance.”
Sounds like you’re talking yourself into using ironpython!
Not that they are the source of all matters in code structure, but there is a reason R# suggests changing explicit types to var. It’s just nicer.
Consider this:
var orderItems = GetOrderItems();
How do you easily what type is returned by this method? The ‘var’ keyword in this examples destroys readability.
@pebbles
If GetOrderItems doesn’t return a collection of OrderItem, than there is something significantly wrong with that function name.
But if you absolutely need to know what type orderItems is, any decent IDE will tell you this very simply.
In short, if you are relying on a type declaration to tell you what type a function is returning, you should reconsider the name of your function.
@Chris – foreach behaviour is actually not tied to those interfaces, it is instead duck-typed by the compiler. The interfaces exist solely to help ensure that people implement the necessary members and to provide a usage hint as to the available functionality. Surprising, but true.
@pebbles – I’m more of a (inferred) static typing guy myself, but it needs to be said that developers using languages that support inferred static typing or even full-on late-bound dynamic typing have been doing just fine for years and years, so the question you should be asking yourself is why are _you_ having that readability issue? Did you name the variable poorly? The method? Is the code around that line a mess that clouds the intent of code? And so on. If you _really_ need the type in place of var, I dare say the code has problems larger than its use of var. 🙂
@Jeremy Gray: cool, I’ll look into the foreach a bit more. I love research after all. Here is a good starter: http://www.csharphelp.com/archives4/archive690.html
@pebbles: the key components are the compiler and your tests. Knowing explicitly that the variable is a particular type does not always help readability. In fact, it often hurts readability — especially when you start dealing with generic types, you get 30 characters of type declaration BEFORE you see any code. And in the end, it tells you very little.
@Stubbs: substitute Pythod for JavaScriptand yes.
The only issue that I have with “var” is that unless you are very careful occasionally it will infer the wrong type. I have had this happen when expecting the value to to be the higher level interface (a interface that derived from IList), but it choose the lowest level (IEnumerable) instead.
@Jeremy Gray
Are you all advocating hungarian notation? I hope not.
How do you know if it’s a fixed array of order items, a list, a sorted list, … ?
Please fix my example so that it’s readable again.
@pebbles: hungarian notation is out. I think most developers see that way these days.
As for the ordered items/list/sorted list question…again, I don’t care. Tell me why it is important to know the difference when I access them the same way. I need to know that when I’m creating the list, and in those cases I keep that in mind. But all of those lists can be traversed with a foreach — so it really doesn’t matter.
Basically, use the IDE (we aren’t programming in notepad anymore), and take advantage of intellesence. Work with your environment, not in spite of it.
I use var, but sparingly. In something like foreach where the scope of the instance is limited, they are invaluable. But I have seen them “abused” a bit in more poorly written code. 90% of the problem is the fact that the code could have been structured better, “var” accounted for about 10% of the headache.
What I am really starting to lose hair over is the upcoming “dynamic” type. Granted, it has a very good purpose behind it, but it is most definitely going to end up being something that will have been abused in many systems I’m brought in to enhance/maintain in the future. If “var” intimidates people, “dynamic” will certainly cause them to fill their shorts.
2 examples of where var keyword shouldn’t be used IMHO:
1)
var myList = new List(); //vs
IList myList2 = new List(); //better since we’re using the Interface to access the instance.
2)
public AClass { public static SomeClass MethodFoo(); }
public BClass { public static SomeClass MethodBar(); }
var ThisAndthat = AClass.MethodFoo();
var ThisAndthat = BClass.MethodBar();
Suppose we are going to alter SomeClass and we want to start by finding references to “SomeClass” to find its usage. Using “var” will prevent us from finding those usages, unless you do “Find references” on both MethodFoo() and MethodBar() as well.
@Juggernaut,
On 1, I can’t say I agree with that. What are you really gaining? I don’t see a whole lot. And actually, you loose a lot of List functionality when you only use the IList. If you are going to pass the list to another method, then the next method can be typed to the IList without any issue.
On 2, ReSharper dude, it has a built in Find by Usage that is beautiful. It will make your life much easier.
@Chris Brandsma
In response to use #1: Juggernaut has the right idea, and so you do in the fact that this isn’t a hard and fast “never use var for List.” It depends entirely upon how your application is structured and how much contract-based programming is in place.
The impetus is on the developer to be aware of their usage of var and the consequences it has.
I absolutely love var for “duh” situations, such as how much easier it makes foreach loops and basic instantiation of variables.