tags:

views:

266

answers:

4

Is there any performance penalty in using the var declaration in c# 3.0+? Resharper is constantly nagging me to use it liberally, and I want to know if there is any downside to it.

+3  A: 

There is no performance penalty, as the type inference is at compiletime. However, it can make your code harder to follow due to the lack of explicit typing.

Cody Brocious
Or easier to follow for exactly the same reason :)
Jon Skeet
It's normally easier to understand provided your initialisation code isn't ridiculously complex. However to me it just feels wrong and I don't mind the extra typing :-) and redundancy of having my types in place of var
Michael Prewecki
For me the most annoying use of var is in a foreach loop...but for variable declaration i'm happy to use either approach
Michael Prewecki
+11  A: 

The var keyword only tells the compiler to infer the type from the assignment, so in essence there's no runtime difference, so no, there's no penalty performancewise.

Whether there are downsides, that's a different story.

Dave Van den Eynde
+3  A: 

No there isn't. The generated IL code is exactly the same. The gain is more readable source code (in most cases anyway).

See also this question.

Brian Rasmussen
+1  A: 

There is no penalty whatsoever. Before effective compilation the compiler replaces the var with the appropiate determined-at-compile-time type. To be more credible I even made a small app to demonstrate this with the use of ex-Lutz Roeder's reflector, now Red Gate's Reflector :

Version 1 :

Code :

namespace ConsoleApplication28
{
    class Program
    {
        static void Main(string[] args)
        {
            var p = new Person("Andrei Rinea");
            System.Console.WriteLine(p);
        }
    }

    class Person
    {
        private string _name;
        public Person(string name) { _name = name; }
        public override string ToString() { return _name; }
    }
}

CIL generated (CIL means Common Intermediary Language ... kind of like Java's bytecode) :

.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 2
    .locals init (
        [0] class ConsoleApplication28.Person p)
    L_0000: nop 
    L_0001: ldstr "Andrei Rinea"
    L_0006: newobj instance void ConsoleApplication28.Person::.ctor(string)
    L_000b: stloc.0 
    L_000c: ldloc.0 
    L_000d: call void [mscorlib]System.Console::WriteLine(object)
    L_0012: nop 
    L_0013: ret 
}

Version 2 (notice the replacement of "Var" with "Person" on line 7 of the code snippet)

Code :

namespace ConsoleApplication28
{
    class Program
    {
        static void Main(string[] args)
        {
            Person p = new Person("Andrei Rinea");
            System.Console.WriteLine(p);
        }
    }

    class Person
    {
        private string _name;
        public Person(string name) { _name = name; }
        public override string ToString() { return _name; }
    }
}

CIL generated

.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 2
    .locals init (
        [0] class ConsoleApplication28.Person p)
    L_0000: nop 
    L_0001: ldstr "Andrei Rinea"
    L_0006: newobj instance void ConsoleApplication28.Person::.ctor(string)
    L_000b: stloc.0 
    L_000c: ldloc.0 
    L_000d: call void [mscorlib]System.Console::WriteLine(object)
    L_0012: nop 
    L_0013: ret 
}

Absolutely no difference in the generated CIL!

So that's all that matters ;)

Edit 1 : This was compiled in Debug mode... prolly in Release the nop's would not be there... ;)

Andrei Rinea