之前我问了一个问题,为什么我看到这么多的例子使用var关键字,得到的答案是,虽然它只对匿名类型是必要的,但它仍然被用来使代码编写“更快”/更容易,并且“只是因为”。

通过这个链接(“c# 3.0 - Var不是对象”),我看到Var在IL中被编译为正确的类型(您将在文章的中间看到它)。

我的问题是,如果有的话,使用var关键字的IL代码会占用多少,如果它在任何地方都被使用,它是否会接近于具有可测量的代码性能水平?


当前回答

如果编译器可以自动进行类型推断,那么就不会有任何性能问题。这两种方法都会生成相同的代码

var    x = new ClassA();
ClassA x = new ClassA();

然而,如果你是动态构造类型(LINQ…),那么var是你唯一的问题,还有其他的机制来比较,以说明什么是惩罚。

其他回答

使用var没有运行时性能成本。尽管如此,我怀疑编译器需要推断类型会有编译性能成本,尽管这很可能可以忽略不计。

“var”是人们要么喜欢要么讨厌的东西之一(就像区域一样)。不过,与区域不同,var在创建匿名类时是绝对必要的。

对我来说,当你直接像这样更新一个对象时,var是有意义的:

var dict = new Dictionary<string, string>();

话虽如此,你可以很容易地做到:

Dictionary<string, string> dict = new和intellisense将在这里为您填充其余部分。

如果你只想使用一个特定的接口,那么你不能使用var,除非你调用的方法直接返回该接口。

Resharper似乎是在使用“var”的一边,这可能会促使更多人这样做。但我同意,如果你在调用一个方法,并且它的名称返回的是什么并不明显,那就更难读了。

Var本身并没有减慢速度,但有一个警告,很多人都没有想到。如果你执行var result = SomeMethod();之后的代码会期望返回某种结果,你会调用各种方法或属性之类的。如果SomeMethod()将其定义更改为其他类型,但它仍然满足其他代码所期望的契约,那么您就创建了一个非常严重的错误(当然,如果没有单元/集成测试)。

我认为你没有正确理解你所读的内容。如果它被编译为正确的类型,则没有区别。当我这样做的时候:

var i = 42;

编译器知道它是一个int型,并生成代码,就像我写的一样

int i = 42;

正如你链接到的帖子所说,它被编译为相同的类型。它不是运行时检查或任何需要额外代码的东西。编译器只是找出类型必须是什么,然后使用它。

我总是在网络文章或指南写作中使用var这个词。

网络文章的文本编辑器宽度较小。

如果我这样写:

SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName coolClass = new SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName();

你会看到上面渲染的预代码文本太长,流出框,它被隐藏。读者需要向右滚动才能看到完整的语法。

这就是为什么我总是在网络文章写作中使用关键字var。

var coolClass = new SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName();

整个渲染的预代码正好适合屏幕。

在实践中,对于声明对象,我很少使用var,我依靠智能感知来更快地声明对象。

例子:

SomeCoolNamespace.SomeCoolObject coolObject = new SomeCoolNamespace.SomeCoolObject();

但是,对于从方法返回对象,我使用var来更快地编写代码。

例子:

var coolObject = GetCoolObject(param1, param2);

以下方法:

   private static void StringVsVarILOutput()
    {
        var string1 = new String(new char[9]);

        string string2 = new String(new char[9]);
    }

IL输出是这样的:

        {
          .method private hidebysig static void  StringVsVarILOutput() cil managed
          // Code size       28 (0x1c)
          .maxstack  2
          .locals init ([0] string string1,
                   [1] string string2)
          IL_0000:  nop
          IL_0001:  ldc.i4.s   9
          IL_0003:  newarr     [mscorlib]System.Char
          IL_0008:  newobj     instance void [mscorlib]System.String::.ctor(char[])
          IL_000d:  stloc.0
          IL_000e:  ldc.i4.s   9
          IL_0010:  newarr     [mscorlib]System.Char
          IL_0015:  newobj     instance void [mscorlib]System.String::.ctor(char[])
          IL_001a:  stloc.1
          IL_001b:  ret
        } // end of method Program::StringVsVarILOutput