Is there anything wrong with using var to declare collections in LINQ queries?
https://stackoverflow.com/questions/1040979
No correct solution
OTHER TIPS
It really depends on the specifics. If it's clear from the rest of your code what type the variable is, or more importantly, if it isn't important to know exactly what type it is, then var
is useful. However, if a type declaration would make sure your code is more maintainable and easier to read, then be more specific and provide the type.
For example, if your query is immediately followed by a loop over the result and that loop is explicitly typed, var
is a reasonable choice as it saves time typing it out and doesn't obfuscate the code to a point where maintenance is much harder, such as:
// uses var instead of IEnumerable<Size>
var items = from item in myItems select item.Size;
foreach (Size size in items)
{
RecalculateLayout(size);
}
In fact, in the example just shown, even Size
could be replaced with var
and the code would still be reasonably maintainable as the typing of the method call would be sufficient.
However, if the query is expected to return a single value and that is then used in arithmetic operations, you should probably use explicitly typed results, as in:
// using var here means you can't properly interpret
// the intention for the following line or where an error
// lies if something changes to say, use double instead of int.
int offset = myItems.First().Offset;
myConvertedValue = originalValue + offset;
I prefer var
. It's short and sweet. Plus if you change from Point3 to Point4 down the road it's one less place to change.
Well, it might be IQueryable instead of IEnumerable.
When I write code, I generally use var by default because it requires less typing and less thinking. At some point before checking in (usually right after I finish the line) I change the var to the precise type.
With the Resharper plugin, replacing 'var' with the actual type is a single keyboard shortcut. In this way I get the best of both worlds. I think having the explicit type makes the code easier to review, so thats what should be checked in.
You won't always know what the type of that IEnumerable
is, that depends entirely on the contents of the Select call. If you're returning declared types, then using var is optional.
Var was created because many times when using LINQ you will create anonymous types, which can't be declared.
The generated IL is identical, so it's a style/personal preference issue.
Personally, I usually prefer to write var, since it's usually very obvious what I'm doing when I'm going to enumerate a collection based on the collection's variable name. That being said, there are times when being explicit can make the code more readable, in which writing it out is beneficial.
I find that, when I write LINQ queries, they tend to change a lot. I might select a single object and later decide I want only specific properties of that object, or combine the properties of two objects into a single object, using anonymous types. Or I might decide I want a list, or just leave it as an IQueryable because I want to add a where-clause to it later if a certain condition is met. Using var
, this works very naturally and smooth. Otherwise you would constantly have to change the type of the result.
In most cases, you don't really care about the type, it's just not important. The query itself tends to hold the more valuable information, rather than the type.
var is better in the sense that it saves typing and can make the code more semantically clear, but it would be wrong to assume that the result is always IEnumerable. IQueryable is also a possibility, depending on the type of collection you are acting upon, and also depending upon the linq statement you are executing!
I believe it depends. You're usually not worried what you're really getting, if a List, a IEnumerable, a IQueryable, or whatever.
IMHO, when the type you're getting is important for understanding, it's better writing the type :).
I feel like explicit is always the way to go here if you are in fact getting back known types. The documentation says that var is required when you are dealing with anonymous types. I see var used all over the place in code not dealing with anonymous types and it feels like lazy coding to me. If we were coding in a duck typed language like Python, I could see using var everywhere but given the situation where you know what types you will get back, I think it's far better to be explicit, not just for you but for future maintainers of the code.
I recently was told that var was the best practice for this scenario, since it's still going to be strongly typed. It's type is determined at compile time and it gets a strong type assigned to it by compiler voodoo.
The point is, var should always "just work" as expected, so use it.
I use the var syntax as another way to self document the code. If it is important to the function logic that the value be of a specific type, then use the type name. If you are just using it as a temporary and the type is not important, then var can help to get that across.
Of course, in quick and dirty apps I use it because I am being lazy :)
I like using var when declaring variables and instantiating the type on the same line, if the type name is a bit long (or uses generics):
var dictionary = new Dictionary<string, string>();
// instead of:
Dictionary<string, string> dictionary = new Dictionary<string, string>();
Or in a foreach-loop where the name of the type of the item-variable is a bit long:
foreach (var item in dictionary) { /* do stuff */ }
// instead of:
foreach (KeyValuePair<string, string> item in dictionary) { /* do stuff */ }
Or in a series of cascading using-statements, to nicely align the items:
using (var inputStream = CreateInputStream())
using (var inputReader = new StreamReader(inputStream, Encoding.UTF8))
using (var outputStream = CreateOutputStream())
using (var outputWriter = new StreamWriter(outputStream, Encoding.UTF8))
{ /* do stuff */ }
// instead of:
using (Stream inputStream = CreateInputStream())
using (StreamReader inputReader = new StreamReader(inputStream, Encoding.UTF8))
using (Stream outputStream = CreateOutputStream())
using (StreamWriter outputWriter = new StreamWriter(outputStream, Encoding.UTF8))
{ /* do stuff */ }