I just watched an excellent presentation by Jimmy Bogard on UI testing with ASP.NET MVC. While I really enjoyed the presentation and got a lot of really good ideas for how to improve how I work with MVC, I saw something that I really did not like: lots of var keywords. Here’s an example (recreated from memory so it might not be exactly right) of one of the methods he showed during his presentation:
... var id = UINameHelper.GetName(expression); var func = expression.Compile(); var value = func(model); ...
What’s wrong with that code? Well, unless I know the API, which I don’t, I don’t know the types of the variables. I can make certain assumptions about their types (the first is probably a string, the next is presumably a Func<T1,T2>, the third I’m not sure about), but I don’t know for sure unless I inspect the code further. Sure, intellisense is going to help, but I don’t have intellisense when I’m watching a presentation or looking at a code sample over someone’s shoulder. I have the code, and that’s it. The code should be readable without an IDE. It should be just as clear when I’m using Notepad++ or looking at it on your blog as when I’m digging through it with VS.NET.
There are times when the var keyword can make code more readable. A great example is when working with complex generics:
//Less readable Dictionary<int,Pair<Foo,Bar>> lookup = new Dictionary<int,Pair<Foo,Bar>>(); //More readable var lookup = new Dictionary<int,Pair<Foo,Bar>>();
So, a request to all my fellow developers out there: please use the var keyword carefully. I don’t think it should ever be used when assigning a variable to a method’s return value. I think it should only be used when it actually *improves* readability of the code, and never when it takes away from it.
Thoughts? Is var the best thing since sliced bread or the worst thing since IE6? When do you think it’s ok to use var?
I agree, for the most part.
But, I think there’s still some cases for using var when assigning a return value from some methods.
var product = model.GetSingleProduct(1);
var products = model.GetAllMatchingProducts(p => p.WidgetType = "foo");
…both are reasonably obvious, even when you’ve scrolled past the declaration.
As a general rule though, I try to avoid using var except when doing so hurts readability (as per your complex generics example), or when I’m using anonymous types.
My first rule is "don’t use var if you are aren’t sure you should or not". Otherwise I advocate using var when:
– The right side of the assignment makes it rather obvious what the type will be
– The type is anonymous (duh!)
– The type is clearly irrelevant to the code block where the variable is created.
– When you are working with code that was designed to be type agnostic using reflection or convention, which are techniques common within the MVC framework.
On that last… basically if you are just setting up variables that will be passed into methods where the parameters are of "System.Object", then you usually don’t need to be concerned with the type in the calling code either. In those cases I find that using var is quite appropriate.
By using var, you are also saying to other developers that may read or maintain your code, "you don’t need to concern yourself with the type here — the type is not important".
it is exactly as you said. fortunately r# provides means to convert between the two. unfortunately it takes almost as long to wait for the r# light bulb to appear as it would take me to substitute the type manually.
It seems to be we are in agreement that the use of var is inappropriate when the type is important. I prefer to use var whenever I can, that force me to use meaningful names in addition to leave out a lot of noise.
The type is important when var evaluates to object or the wrong type, which it does in foreach loops over untyped collections. Or when it’s meaningless, like declaring uninitiated variables.
Other than that, when is the type important to us, the readers?
I still think the type is often important, even with very readable code. Take this for example:
var productView = repository.GetProductAndManufacturer();
While I can be pretty sure that whatever "productView" is likely contains information about a product and manufacturer, it’s still not very informative. If I know the type (and am familiar with the type), then I know exactly what productView contains.
This is the best post on this topic i have ever read.
I loved the way you exlained things. Much better many here
Thanks for taking the time to discuss this, I feel strongly about it and love learning more on this topic. If possible, as you gain expertise, would you mind updating your blog with more information? It is extremely helpful and beneficial to your readers.
Using var everywhere and feeling great when someone cries about it.