CC0001: Show it only where appropriate
See original GitHub issueBug
In my opinion, the CC0001 should only be shown in cases which makes sense and where type declaration is redudant and not show warnings where it’s not redudant and were var wouldn’t hide information important for reader of the code.
For example, the warning should come only when there is a new operator on the right side.
//the code that reproduces the bug
List<string> tags = new List<string>();
User user = repository.Get<User>(5); // where repository is a generic repository
IEnumerable<User> users = repository.GetAll<User>(); // where repository is a generic repository
List<string> tags = GetTags();
int count = 0;
Current warnings and fix suggestions:
var tags = new List<string>();
var user = repository.Get<User>(5);
var users = repository.GetAll<User>(); // where repository is a generic repository
var tags = GetTags();
var count = 0;
Expected warnings and fix suggestions:
var tags = new List<string>();
var user = repository.Get<User>(5);
IEnumerable<User> users = repository.GetAll<User>();
List <string> tags = GetTags();
int count = 0;
Both suggestions are related to Code Reviews.
The reason for this is, that var tags = new List<string>();
hides no information, because it’s obvious from the assignment that the type of tags is List<string>
. On var tags = GetTags();
however, the information is hidden away as it’s not obvious that GetTags()
may have List<string>
as return type. It could also be List<Tag>
and we won’t see it until we inspect the tooltips.
For scalar types, var shouldn’t be shown as warning for several reasons, main one being being that in code reviews it becomes harder to track changes, i.e. if var count = 0
gets changed to var count = 0.0
(or change from float to decimal whlie using var) it may have impact on further calculations.
Last but not least, if a generic method type matches the type left of the assignment operator, the warning should suggest using var. If it do not match, it should not suggest it.
Above are two samples of that:
var user = repository.Get<Tag>(); // returns T
IEnumerable<User> users = repository.GetAll<User>(); // returns IEnumerable<T>
Having User
feels redudant in User user = repository.Get<User>(5); // returns T
when the return type is the type used in Get<T>
and brings no additional information from a code review perspective.
in IEnumerable<User> users = repository.GetAll<User>(5);
it’s different, because GetAll<User>()
doesn’t return User
as may think by quick reading of th code and while “GetAll” suggest it’s a collection, we don’t know if it’s User[]
, IEnumerable<User>
, IList<User>
or some custom implementation maybe called UserCollection
, so having a var here will be a loss of information.
This samples above match with the overall guidelines on when and how to use the var
keyword. It should only be used, when the declaration on the left side is redudant.
Or at least an option to enable/disable between the current and the described behaviour, with preference to have this behaviour as default.
Issue Analytics
- State:
- Created 7 years ago
- Comments:24 (14 by maintainers)
I want
var
everywhereI disagree, I like
var
everywhere. But I would like to know what everyone else thinks, other users, @code-cracker/collaborators and @code-cracker/core.