C#’s “var” keyword considered harmful

As a software developer working with C# you’ll most likely have formed an opinion about the var keyword. You either hate it with a passion, you may love it (with a passion), you may simply be a moderate and use it in very specific cases.

The var keyword provides type inference during variable declaration. It doesn’t have anything to with Javascript’s var, it doesn’t make the soundness of the type system used in C# weaker and it probably wouldn’t have existed without LINQ and the need for anonymous types. But you probably know all this already.

There are so many questions in stackoverflow.com in regards to what the community thinks var’s acceptable usage should be and there’s even information about the equivalent keyword in VB.net (apparently there isn’t one, but there are ways to shoot your foot off instead: http://stackoverflow.com/a/2489467 ). But does the community’s opinion matter?

You see, most people of the global C# developers community will probably identify as “var-moderates”and will only use var where there’s no possibility of confusion (such as when creating an instance using its constructor with the new() keyword). Sounds fair and I actually support this opinion. But I don’t actively use this approach unless required by my team’s coding standards.

 

I would classify as a var-extremist in that I try to use var everywhere. The only slight exceptions I make is when I cannot avoid it (think TryParse methods) or where I need static polymorphism between classes (rare, but it happens). My reason for choosing this approach has to do with the type inference in functional languages. Even though I have never had a full time job involving any functional language (pure or not), I have worked with F#, Haskell and some Scheme and when I managed to rewire my brain and understand the functional approach I just fell in love with it. After all, one of the main reasons I like C# so much now is exactly because of the functional aspects they’ve added and kept adding to it.

 

Why this post then? The primary question that comes to mind is whether the need to know the type is important or not. Proponents of var would usually claim it’s not; it’s your design that matters, but they’ll (usually) concede that you can mouse-over the var keyword to see the type. Opponents will say that having more information at hand can’t be bad, on the contrary it gives you more power.

 

To me, var represents something more important:

C# can be a verbose language. Very verbose actually, especially if you consider its first version where it was very close to Java, a language that’s verbose like no tomorrow. And, while I like Object Oriented Design and its derivatives, I really like to have my code be as concise as possible. I don’t want to reach quite the level of (almost) esoteric functional language level of concincess, but I will gladly trim as much fat as I can. And this is why even Java slowly accepts this paradigm.

Have a look at the following simplification introduced in C# sometime in the past:

delegate void TestDelegate(string s);

public static void Main(string[] args)
{
	TestDelegate testDelA = delegate(string s) { Console.WriteLine(s); };
	TestDelegate testDelB = s => Console.WriteLine(s);
}

Ironically, this is an example where var is invalid. But I digress; the point is to indicate how a simplification of the language, using inference makes the code simpler and easier to understand. Yes, you don’t have the type in front of you (assuming that the delegate declaration was in another file) but it’s not difficult to discover and use it. You can obviously declare the type of s in the second example, but does it actually offer any significant advantage in order to warrant manually typing it?

 

To me, this is an example of where a minor concession leads to a greater benefit and this is one I’m happy to make. Comparing Java (pre-lambda Java) and C# is a good indicator of the difference between those two approaches: explicit vs implicit, declared vs inferred. Some years ago I wouldn’t imagine preferring convention over configuration, but look at me now; no turning back unless actually needed. Similarly, while in theory being explicit as much as you can (Java) offers you more information at hand, you end up with a tiring and not as flexibile result that requires more effort to actually understand.

Might be anecdotal, but I definitely find harder to understand large pieces of explicit code, compared to smaller but succinct ones that leverage convention and inference. And for that, the var keyword is a friend, not something to fear, but something that should be embraced, even if you don’t want to go all the way, like I did.

Leave a Reply

Your email address will not be published. Required fields are marked *