Feeds:
Posts
Comments

Archive for April, 2008

The “var” controversy

There’s some blog buzz going on right now about the appropriateness of using the new C# "var" keyword.  I first ran across the meme from Jean-Paul S. Boodhoo’s blog, with this post.  He later linked to a post by Ilya Ryzhenkov on the same subject.  One of the responses on Ilya’s blog read:

"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."

This response was quoting a post by Rob Conery.  Let me first say, I have not read all of Rob’s post (mostly because the formatting is so bad, it makes it hard to read the post, and I don’t have the time to spend on the effort).  Maybe this quote is taken out of context, so take what I say next with a grain of salt.  This quote is utter hogwash.  The "var" keyword produces no extra code.  Prove it to yourself.

public class Foo
{
}

class Program
{
    static void Main(string[] args)
    {
        Foo explicitFoo = new Foo();
        var inferredFoo = new Foo();
    }
}

The resultant IL that’s generated is this.

.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 1
    .locals init (
        [0] class Playground.Foo explicitFoo,
        [1] class Playground.Foo inferredFoo)
    L_0000: nop 
    L_0001: newobj instance void Playground.Foo::.ctor()
    L_0006: stloc.0 
    L_0007: newobj instance void Playground.Foo::.ctor()
    L_000c: stloc.1 
    L_000d: ret 
}

The code for the explicitly declared variable and the inferred though "var" variable is identical.  Do NOT fear using "var" because of performance concerns, as there is none.

With that out of the way, where do I fall in opinion on this subject?  Well, reading the various posts in this meme, there seems to be two camps.  I think both are extremes.  The first extreme is the "Microsoft Camp".

“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 simply can’t agree with this extreme viewpoint.  Tell me how the following code can possibly be considered less readable for others?

var inferredFoo = new Foo();

The other camp, which I’ll call the Boodhoo camp, though I don’t have proof that Mr. Boodhoo specifically takes this extreme point of view, believe that you should always use "var".  I can’t agree with that extreme either.  Can anyone tell me what the type of the following declaration is?

var current = Foo.Current;

We can have arguments until we’re blue in the face about how better naming would have prevented this confusion.  I don’t buy the argument, though.  First, names aren’t always under your control.  Second, even with better naming it’s still possible to find yourself in situations where you don’t have enough type information available to you in situations like this.  C# is still a strongly typed language, and knowing the exact type your dealing with is important.  Relying on the IDE is a no go for me, and relying on naming isn’t always possible.

So, what do I think?  Out of habit, I’m still not using "var" that frequently, but I see no harm in using it for your typical "new" statements like the first example.  I don’t know if I’ll get into the habit of doing that or not, but I see no reason to try and talk anyone out of doing so.  For other declarations like the second example, unless the type is anonymous, I’d probably favor the Microsoft guideline of not using "var" here.  You can probably get away with it 80% of the time and I won’t care, but that other 20% is enough reason for me to not recommend getting into this habit.

Edit:  From a reply to Ilya’s post by "Simon" we get a list of rules much closer to what I think makes sense.

  • Do use var for anonymous types
  • Do use var for initialization from constructors (var list = new List();)
  • Do use var for casts (var list = (IList)list;)
  • Consider using var where naming implies the type of the variable (var xmlSerializer = GetXmlSerializer();)

The last bullet point is the most controversial, but I can agree with it as long as developers are consciously considering the choice.  For the rest, I can see no reason to recommend not using "var" in any of those situations.

Advertisements

Read Full Post »