Reputation: 3274
I am using ReSharper to help me spotting possible errors in my code, and, although not an error, it keeps complaining that I should use the var
keyword instead of explicitly typing variables on the declaration. Personally, I think it is much more clear for me and for anyone reading my code if I write
IList<T> someVar = new List<T>();
instead of
var someVar = new List<T>();
Knowing that there're no performance differences between both ways, should I ignore these hints or stick with the var
keyword?
Is it only a matter of taste or is it a good practice to implicitly type variables?
Upvotes: 3
Views: 2618
Reputation: 38444
It's mainly a coding style issue (with the exception of anonymous types). Personally I often use var when writing code, but use ReSharper's code cleanup to convert them back to explicit typing when I've finished. This allows me to write code more quickly, but then convert the code to something I feel is more readable by myself and others (after all code is written once but read many times).
I turn off ReSharper hints for using 'var' by turning off the following "Language Opportunity Settings" (found in Options, Code Inspection, Inspection Severity):
Use 'var' keyword when initializer explicitly declares type.
Use 'var' keyword when possible.
You can configure ReSharper to convert 'var' to explicit type in Code Cleanup settings under:
Use 'var' in declaration
Upvotes: 2
Reputation: 6258
This is a great question for a junior developer. Not necessarily that the asker is junior, but that ensuring clarification prior to presenting information to a junior developer is a great thing to do.
In that spirit, whoever finds this question should always understand that readability is one of a few Quality Attributes, and certainly one of the most important to master early on. Readability includes variable naming practices and explicit code, to name a couple.
That said, one individual micro-aspect of readability is whether or not to use implicit typing via the var
keyword. The short answer is Maybe. An educated answer with examples might narrow Maybe down to Rarely.
So, to make this easiest to understand, I'm going to begin with reasons not to use implicity typing via the var
keyword.
(Language Perspective) The first reason not to use implicit typing is because a major strength of C# is that it is a strongly typed language. There are plenty of wonderful languages whose strengths include NOT being strongly typed such as Javascript. Every language is different and has its own strengths/weaknesses. For C#, being strongly-typed is one of its most important strengths.
This answer assumes that your code is SOLID. If you are working in a legacy code-base, or are a junior developer who hasn't quite achieved full focus on dependency injection or Liskov Substitution, then micro-tuning your var
usage isn't where your focus should be right now.
There are only a few ways to assign to a variable. These are the ones I think of right now:
ISomething someVar = new Concrete(); // <1. Can't use var to create Interfaces.
var someVar = GetFromMethod(); // <-- 2. Taken from return type
var someVar = new MyPerson(); // <-- 3. Custom complex reference type
var someVar = new DateTime(); // <-- 4. Built-in simple Reference Type
var someVar = string.Empty; // <-- <<
var someVar = new List<T>(); // <-- 5. Built-in complex Reference Type
var someVar = new Dictionary<string, Dictionary<int, List<MyObject>>>();
var someVar = true; // <-- 6. simple Value type assignment
var someVar = 1; // <-- 7. complex Value type assignment(s)
var someVar = 1.0; // <-- <<
var someVar = 1.0d; // <-- <<
foreach (var i = 0; i <= . . .) // <-- 8. Same as 7 above, but different context.
var someVar = new {Name = "yo"}; // <-- 9. Instantiate Anonymous Type
(Breakdown)
1. In example 1 of the above examples, I illustrate the only time you simply cannot use the var keyword. You obviously can't create a concrete instantiation under an Interface. I get into more specifics about using Interfaces in #5. Don't Can't use var here
2. Example 2 assumes somebody is using the same development tools as you, and that everybody wants to take the time while reading code to investigate the return-type of methods. Depending on how fast you read code or code-review, this could be an insignificant or a major drawback. Don't use var here
3. Why are you instantiating a newable in-line? As I said earlier, these examples assume you practice SOLID principles. This way of declaring a variable creates a code smell. If you search your codebase for the new
keyword, the only results should be in auto-generated code, a composition root, or for #4 below. Don't use var here ever do this
4. new DateTime();
, and a couple other rare Built-In simple types are some of the rare times you should see the new
keyword in your codebase. Using the var
keyword in example 4 isn't that big of a deal. But honestly, what are you buying by fighting to be implicit in this situation? Same question for the string. Can use var here... but why?
5. You should always try to use the least specific type possible. In short, that means use small interfaces. This rule mostly applies to external-facing API's because you want to keep changes as flexible as possible without breaking a consumer. The only reason this rule is NOT strictly applied to internal code because if a developer wants to make a breaking change, they have the capability to take extra time and do extra work to cascade break-fixes. That's not a very good excuse.
.....5.1 So for the first part, note that someVar becomes the type Generic.List<T>
. If you're wanting to create a variable of type IList
, as I can see you do, then using the var
keyword is not what you want. This is generally the rule for declaring variables with the least specific type possible. Look at: IList vs List. What if you purposely don't want to allow the usage of your variable to include all that extra junk in List<T>
? There's a reason for these rules. Try Not to use the var keyword if you can follow this rule.
.....5.2 Assuming you don't care, or don't want to use interfaces as suggested, this is fine. This also somewhat applies to the idea of length. If you have nested levels of collections and your declaration is long, nobody would blame you for using the var
keyword. Okay if you aren't using Interfaces
6. This is similar to example #7, but applies to Non-Numeric value types. The simple question is, "Why?" Just as I said in #4, what are you buying? Assuming you are going with the Default value, you'll have to specify the type anyway. Why mix rules, and what does it buy? Sure, but why?
E.G.: You have to be explicit sometimes anyway, why mix rules?:
bool isVarOkay, canUseVar;
char a, b, c, d, e, f;
bool isSample = true;
byte etc;
var isOtherSample = true; //<-- why?
7. There are a bunch of numeric value types. Most of the reasoning for that is for precision, and some is for semantic purposes. Either way, why let the compiler guess at what you want instead of being explicit. If there was ever a time to be explicit, numeric value types is the time. As far as plain-ol int
goes, perhaps there is some leeway to use var since it is so direct and obvious. But I'd rather save that for point #8. Don't use the var keyword
8. This code structure is used in so many places, that it almost seems okay to do it. But once again: Why, and what are you saving? var
and int
are both 3 characters. Sure, but why?
9. In the case of Anonymous returns, you almost have to use the var keyword. Not doing so sort of defeats the purpose of being Anonymous. Most Anonymous types can be inlined so that their results are immediately transformed into something useful, so they don't necessarily have to be assigned to a variable. But there are some occassions for this that are not worth avoiding. Use var for Anonymous Types if necessary.
Conclusion
The var
keyword is unavoidable for Anonymous types. Also, it can be helpful for Generic types with multiple levels of generics which make for a long declaration like Dmitry's example Dictionary<string, Dictionary<int, List<MyObject>>>
. Lastly, it wouldn't hurt anybody's feelings if you use the var
keyword in the examples shown in numbers 4, 5, 6, and 8. But you aren't buying anything.
The idea that using the var
keyword allows you to change the type, or allows you to stick to the DRY principle, is nothing but a bogus excuse. Only in rare situations does the Assignment-side of the declaration properly represent what the Type is supposed to be.
Upvotes: 1
Reputation: 7352
I only use var when the type declaration is too long (15+ chars). Otherwise explicit declaration is more readable.
To disable it in Resharper 8.2, go to Resharper > Options > Code Inspection > Inspection Severity > Language Usage Opportunities. Typing the word "Use" on the search box is helpful to filter down the list.
Upvotes: 2
Reputation: 10118
I see at least two reasons.
First, its the matter of DRY principle: don't repeat yourself. If in future you decide to change type of variable from List<>
to Stack<>
or LinkedList<>
, then with var
you'd have to change in one place, otherwise you'd have to change in two places.
Two, generic types declaration can be quite long. Dictionary<string, Dictionary<int, List<MyObject>>>
anyone? This doesn't apply to simple List<T>
, but you shouldn't have two code styles for different object types.
Upvotes: 5
Reputation: 108810
It's just a matter of style. I tend to favor var
if the type of the right side is immediately obvious like in your example, but if you don't like var
it's perfectly fine to disable that rule. Many programmers prefer explicit typing.
Check out Eric Lippert's blog article Uses and misuses of implicit typing for an extensive discussion of when var
is appropriate.
Upvotes: 3
Reputation: 25742
It's just a matter of being concise, just like auto-properties. Stick with what you feel most comfortable.
Upvotes: 1