Is var good, bad, or ugly?
On var and C#
Dan Fernandez wrote recently on the var keyword in C# 3.0. He is very
thorough about how var works. I’m going to try and add to his commentary with
discussions about my initial thoughts on best practices for var and C#. The
usual caveats apply: This is some initial impressions, because it’s new to all
of us. I’m still making up my own mind about when it’s best to use var, and when
it’s best to avoid it.
Dan starts with this simple example (pasted from the blog posted linked
below):
Before 3.0
string myString = “hello”;
int myInt = 5;
float myFloat = 5.5f;
After 3.0
var myString = “hello”;
var myInt = 5;
var myFloat = 5.5f;
It’s critical that you understand what the C# 3.0 compiler does with respect
to typing here. In both cases, the IL will show that myString, myInt, and
myFloat are string, int, and float, respectively. It’s not weakly typed, or even
‘object’ types.
So, the first complaint comes: “Doesn’t this just make the code less
readable?”. In this instance, my answer would be ‘yes’. This simple example is
simply not a good usage for the var keyword.
Pulling one of his later examples (same blog entry), you can see why var was
added to the language:
var result =
from s in aBunchOfWords
where s.Length == 5
//Creates a new anonymous type
with name/value pairs
selectnew {Value=s, Length=s.Length,
FirstThreeLetters=s.Substring(0,3)};
//Print
values
foreach (var x in result)
Console.WriteLine("Value: {0}, Length:{1},
SubString:{2}",
x.Value, x.Length,
x.FirstThreeLetters);
This
prints:
Value: Hello, Length:5,
SubString:Hel
Value: World,
Length:5, SubString:Wor
Now you see why var is needed: The type of ‘result’ is
IEnumerable<something>. The only problem is that ‘something’ is named by
the compiler: you have no idea what is it.
The conclusion: Without ‘var’, LINQ gets too painful to use. You’d need to
define your own types for every different query you generate in every
application you write. It’s not that useful, and we’d probably end up with the
same kind of code we have now. You know, you’d define a type that contained
every column and then just leave some columns as nulls on any query that doesn’t
use them. Wasteful, and error-prone.
Great, that’s two very obvious examples: when var is almost necessary, and
when var just creates poor code. Where life gets very interesting is when you
fall somewhere in the middle. On the one hand, using var to save typing might
make sense in some occasions. The right hand side of the assignment is
sufficient to create clarity:
var rect = new Rectangle ( … );
var result =
myCollection.GetEnumerator();
The second line doesn’t necessarily tell me the type of result, but I can
easily get a good understanding of what it is. I’m not sure I prefer var, or
naming the variables.
Other uses get closer to the unreadable case:
var thing = MyClassFactory.CreateThings();
I intentionally chose rather vague names to increase the un-readability of
the code. In practice, context, and better class names probably makes this
construct a reasonable practice.
So, what do I really think about var, its usefulness, and its effect on code
readability? First of all, var is needed in LINQ. So get used to it. Secondly,
two reasonable coding practices you should be using anyway will keep code
readable, even if everything were declared with the ‘var’ keyword:
First, define class (or struct) names that clearly state the type’s purpose.
Vague names create unreadable code.
Second, shorter methods will improve readability. If you can see the
initialization of a type, you know what it is, or at least what the usage is for
that type, in that method.
So, var can decrease readability, but I think that will be a problem if your
code is already not very readable.
LINQ: The purpose of var
Does it help or hurt readability