- It is required to express variables of anonymous type. This is pretty obvious - you cannot declare local variable of anonymous type without using var.
- It induces better naming for local variables. When you read local variable declaration with explicit type, you have more information at that moment and something like "IUnitTestElement current" makes sense. However, when this local variable is used later, you read "current" which takes some time to figure out the meaning. Using "var currentElement" makes it easier to read at any place.
- It induces better API. When you let compiler deduce type from method return type or property type, you have to have good types in the first place. When you don't have explicit type in the initialization expression, you have to have best names for members.
- It induces variable initialization. It is generally a good practice to initialize variable in the declaration, and compiler needs initializer to infer type for local variable declared with "var" keyword.
- It removes code noise. There are a lot of cases, when implicitly typed local will reduce amount of text developer needs to read, or rather skip. Declaring local variable from new object expression or cast expression requires specifying type twice, if we don't use "var". With generics it can lead to a lot of otherwise redundant code. Another example would be iteration variable in foreach over Dictionary<TKey,TValue>.
- It doesn't require using directive. With var, you don't have explicit reference to type, as compiler infers type for you, so you don't need to import namespace when you need a temporary variable.
To summarize the list above, by actively using var keyword and refactoring your code as needed you improve the way your code speaks for itself.
PS: Visit ReSharper at Visual Studio Gallery!

37 comments:
C# Reference recommend to use var only in case of anonymous type.
“Overuse of var can make source code less readable for others. It is recommended to use var only when it is necessary, that is, when the variable will be used to store an anonymous type or a collection of anonymous types.”
http://msdn2.microsoft.com/en-us/library/bb383973.aspx
Yeah, Microsoft often tries to make things "safer". I don't agree with them here :)
Ilya -
For all the times I've agreed with you, this time I'm not convinced. The argument that it forces better naming conventions just doesn't work for me. I want good naming conventions from my developers whether or not var is involved (and Resharper really helps with make that easy!).
Other than for the obvious use with anonymous types, which the use of var can help highlight, and the perhaps simple variable initialization:
var name = "Ilya";
or
var currentIndex = 1;
I'm not sure I favor it. When I see:
var latestUpdate = GetLatest():
it doesn't tell me what latestUpdate returns.
I'm just moving projects to 3.0 so I'm keeping an open mind on this. I'm wondering if you are considering allowing configuration of the var suggestion only in the case of simple initialization?
Thanks for sharing your thoughts on this - jlo
Jeff,
var latestUpdate = GetLatest();
is quite good example of "It induces better API" principle. GetLatest should probably be renamed or otherwise refactored.
“Overuse of var can make source code less readable for others. It is recommended to use var only when it is necessary, that is, when the variable will be used to store an anonymous type or a collection of anonymous types.”
I agree with Alexander. Var should only be used for anonymous types. It was designed for anonymous types and for use with LINQ. Using var to implicitly type local variables is not good practice and makes code more unreadable.
"var latestUpdate = GetLatest();"
I knew you were going to say that :>
As I said - I have an open mind...
Merlin,
You are just restating what Microsoft told developers in their usual safety manner. What exactly do you think is less readable? Why var should be used only for anonymous types?
I'm keeping an open mind... Here's a post by Rob Conery which contains some additional thoughts:
"The upshot here is that vars generate some serious code - all for good reason when using LINQ. But NOT for a good reason if you’re being lazy - which is the point of this whole post. If you find yourself using “var” anywhere that’s not within a LINQ statement, it’s probably not a good idea."
Brent,
That's all wrong. Using "var" doesn't generate any code. Compiler just infers the type and then acts as if this type was typed in. The code is being generated for anonymous types, not for vars.
Great list Ilya.
The last was one I'd not quite registered consciously, although now that I think back over the past 6 months of steadily increasing use of var, I think it's definitely been an influencing factor...
Jeff:
Just FYI, and putting aside the renaming possibility for the moment, in my experience I've actually found it really useful to be able to implicitly change the return type of these sorts of creational/factory methods. If at some point later you that an extract interface / split interface/class refactoring is appropriate (perhaps 80% of usage is of a logical subset of the original interface) then implicit typing can reduce the amount of manual change in some scenarios...
To borrow from your example, you may decide to split the LatestUpdate into an interface providing meta-data only, and another one containing the full content of the update...
If most usage just needs the MetaDataForUpdate interface/class, the GetLatest can just return that...
With implicit typing, you avoid having to change the locals calling this method, but the compiler will still catch the 20% of usages that actually need the full ContentOfUpdate (because they are attempting to call a FileBytes property which does not exist on MetaDataForUpdate), and you can just work on that smaller proportion of code.
During refactoring, it almost acts like a strongly-typed version of Duck-typing (http://en.wikipedia.org/wiki/Duck_typing)
This is definitely a minor scenario, and despite the length this comment ended up being :), I don't mean to overstate it... BUT it can be quite convenient.
Most commonly I've found it useful when trying to increase unit test coverage in existing codebases, where there may be numerous existing tests that each create an instance.
Here, running extract interface to facilitate a mock or fake implementation becomes just a little bit easier... For an example, see below.
(Of course, horses for courses, and it won't appeal to those who like both suspenders and a belt... :)
Matt
We can change
class Duck
{
void TalkQuack();
void WalkWaddle();
}
Duck CreateDuckInstance()
{
return new Duck();
}
// line of code that exists in N unit tests...
var speaker = CreateDuckInstance()
To (bold indicating changes)
interface IDuck
{
void TalkQuack();
}
class Duck
{
void TalkQuack();
void WalkWaddle();
}
namespace Tests {
class MockBushLameDuck
{
void TalkQuack();
void CantWalkIsLame();
}
}
Duck CreateDuckInstance()
{
if (Testing)
return new Tests.MockBushLameDuck();
else
return new Duck();
}
// line of code that exists in N unit tests, and can remain unchanged...
var speaker = CreateDuckInstance()
Oops, lost the important bit of the example while playing with formatting:
Duck CreateDuckInstance()
To
IDuck CreateDuckInstance()
I was wondering if this issue was revisited by you Ilya. Are you thinking about leaving this suggestion the way it is now?
After reworking some code and using var wherever possible, I can't say it has provided any benefit and at best obfuscates meaning in most situation.
I can see it as a reasonable substitution in construction:
var jeff = new Jeff();
and with LINQ. After that I don't see the benefit.
I hope the the hint capability will be expanded somewhat to take the various preferences into account.
I really am having a hard time to read code with too many vars - it's just a reduction of information. While you may say that it "forces" devs to go with better variable names, I'd still opt for explicity typing *and* good variables (and people who don't care will still use bad naming schemes)...
I'd also disagree.
Sounds to me like "It makes your code less readable, so forces you to make it more readable".
to add more fuel to the fire...
These are my tentatively self imposed rules
-Do use var for anonymous type
-Do use var for constructors
eg var list = new List();
-Do use var for casts
eg var Ilist = (IList)list;
-Consider using var where the variable name implies the type of the variavle
eg var xmlSerializer = GetXmlSerializer();
The idea is to use var where it does not obfuscate the code
With these in mind it would be great if in the resharper config we could define different cases when the var hint is shown.
Right on, Ilya! Good stuff!
The only thing better than the var keyword would be no keyword at all.
Ruby has forever changed my opinion on necessary keywords and code noise.
Completely agree with using var instead of actually typing out the variable type name. It's much quicker, concise and increase the percentage of code typed which actually reflects the algorithm.
One nitpicky detail. "var" is not required to declare an anonymous type variable. You can use type inference to get around this.
static void Example1<T>(T value)
{
T local = value;
}
static void Other()
{
Example(new { Name = "foo"});
}
I started a while back with the idea I didn't like var as it would make my code look meaningless and I would need to read methods to figure out what they returned.
I rapidly realised that var was helping me to name methods and properties in a better way, and that removing half a screen width of pointless declaration was a massive boon to code clarity.
Use them, love them, worry if you cannot figure out what an object does by it's name, don't blame var for you having poorly named fiunctions :)
"The only thing better than the var keyword would be no keyword at all."
Oh dear me no. From bitter experience, I'm not a fan of declaring new variables whenever I mis-spell/capitalise an existing variable name.
Ruby has forever changed my opinion on necessary keywords and code noise.
That's an interesting way to put it. I remember back in 1983 when I went from BASIC to Pascal, and it took me a bit to understand this concept of declaring variables before using them.
Ultimately, I've come to conclude that the declaration is useful because it forces you to actually think about what you are doing ahead of time.
Apparently you disagree? Should we just go back to BASIC and Fortran? Can we get more done by not having to declare variables?
Before var existed, was anyone in the community thinking "my code would be so much more readable if only I didn't have to type all my local variables"? No, of course not. It was pretty much invented only to support Linq. The fact that it can be used for non-anonymous types doesn't mean it should.
Indeed, I feel your points are mainly spurious. For example, points 2, 3 & 4 are essentially saying "because some coders follow porr practices, everyone should remove useful information from the code". While point 5 refers to the useful information as "noise". The compiler can infer the type, yes. Poor maintainers, however, shouldn't have to work to do this, they should see it explicitly stated.
Who are all of these people that are scrolling back up to the variable declaration or using "Go to declaration" to determine the type of a variable rather than simply hovering over the variable?
Are you guys using something other than Visual Studio for C# development? Monodevelop, perhaps? Doesn't it provide similar features?
It seems to me the flexibility and the Don't Repeat Yourself (DRY) principal demand var usuage wherever possible, and I don't see how this adversely affects practical readability if your variables and APIs have descriptive names.
If you are relying on the variable type to make your program more readable, then you aren't using descriptive enough names. Besides, that also implies that knowing the variable's type affects how you use it, rather than simply using IntelliSense to go member-shopping, as I'd bet most of you do anyway.
It just seems goofy to pretend that you are programming with vim, emacs or notepad, when the IDE takes care of any practical concerns introduced by var declarations.
Brian,
What is the exact connection between var and DRY principles? I don't get this part.
Besides, code readability > everything else.
Ray, please read my comment again. Readability isn't hurt.
XslSettings xset= new XslSettings();
var xset= new XslSettings();
The first statement is repetitive. DRY.
I think that using "var" (type inference) is also consistent with modern functional programming ideas realized by such languages as Scala and F#.
In Programming in Scala Martin Odersky emphasize on how
val greetStrings = new Array[String](3)
is generally better than
val greetStrings: Array[String] = new Array[String](3)
because it does not repeat unnecessary Array[String] (both styles are valid in Scala).
P.S. I basically agree with what Brian said. Most of the time DRY applies, but as Martin Odersky likes to say, "had you been in a more explicit mood, you could have specified the type ... explicitly" :)
BTW, C#, F#, and Scala are better here, than Ruby, because they still use static types.
From the points made in the main article it seems this type of refactoring is unique amongst all the great recommendations that resharper makes. This rule makes your code worse until you can manually refactor or rename existing code to add in some meaning that has been removed.
Reshaper is a great tool because it simply lets me refactor code to be better with a few mouse clicks. I don't think resharper would be as great if it had a bunch of rules that only took you halfway to the goal.
I think the decision to keep this feature is a philosophical decision for the Resharper dev team. Are these halfway rules what you want to include into your otherwise concise and complete rule set.
Personally i don't like this rule. If a member of my team used a "var" where it wasn't necessary i would ask them to change it. I would actually like a reverse rule for this. "Don't use unnecessary implicitly typed locals"
Seriously, why are you navigating back to the variable definition to determine the type of variable?
No one seems willing or able to answer this critical question, which is the entire basis of the "type name adds meaning" argument.
I've turned off this recommendation and am telling my developers to do the same. Variable type declaration is not equal to variable instantiation. Therefore, you should only use var when you must. I've fought far to many battles in classic ASP and vbscript where the type I thought was going into the variable wasn't the type I ended up with.
"Variable type declaration is not equal to variable instantiation."
If this were true, the compiler would be unable to infer the type.
"I've fought far to many battles in classic ASP and vbscript where the type I thought was going into the variable wasn't the type I ended up with."
Comparing a dynamic language with a strongly-typed one isn't a great way to develop best practices.
Yet again, I have to ask why people are scrolling to the point of variable declaration to determine the type, rather than just hovering over the variable.
"Yet again, I have to ask why people are scrolling to the point of variable declaration to determine the type, rather than just hovering over the variable."
That's supported in Visual Studio only. What if you're reading code on paper, on a web page, pdf or plain text editor?
"What if you're reading code on paper, on a web page, pdf or plain text editor?"
If that's a primary design concern, I worry about your development process.
"If that's a primary design concern, I worry about your development process."
I guess you've never heard of code reviews.
"I guess you've never heard of code reviews."
Sure, we do them too, just not on stone tablets.
Ok, let say that you have something like this.
var message = Inbox.GetMessage();
How do you know if the message is an IMesssage, Message of even just a string?
You say that I should rename my method....do I have to call it Inbox.GetIMessage() or even worst...Inbox.GetStringMessage()???
And by the way, maybe I dno't even have access to this code..maybe iI' using a dll from another provider. You should NEVER change your coding convention because of that.
Naming all your method depending on the return type is totally stupid. That's exactly why Microsoft says to not overuse the var keyword. I agree that var should (could) be used when declaring long named type objects like in this example.
//this is long for nothing
MessageProvider messageProvider = new MessageProvider();
//this is ok
var messageProvider = new MessageProvider();
It should also be used with LINQ. But THATS IT! Don't use it with method. Don't use it inside loops. Stop using var just because you can. If you don't like strongly typed language, go with Ruby or Python and stop blogging about C#.
"How do you know if the message is an IMesssage, Message of even just a string?"
You hover over the variable name. But you probably don't even need to do that, unless you have memorized the entire API/library, which would be a waste of time. In reality, you type the variable name, then a dot, then you shop for the property or method you need, just like everything else.
Post a Comment