2011-10-24 191 views
2

是否有这样的构造和分配类的属性之间显著性能差异(在运行时和/或编译时):构造基于对象初始化

Employee currentUser = new Employee(); 
currentUser.Name = "Bob"; 

或这样的:

Employee currentUser = new Employee() { Name = "Bob" }; 

我的实际例子并不那么简单,该类的属性实际上分配给了一些long linq表达式。

我搜索谷歌和堆栈溢出的答案,但我只发现有关最佳做法,何时使用任何方法,而不是任何性能相关的问题。

如果我问一个愚蠢的问题,提前道歉。

回答

3

不,这只是一个语法糖。产生将是相同的IL

internal class Foo 
{ 
    public string Bar { get; set; } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     Foo f = new Foo() 
        { 
         Bar = "Baaz" 
        }; 
     Console.WriteLine("Now the old way sugar"); 
     Foo f2 = new Foo(); 
     f2.Bar = "Baaz"; 

    } 
} 

现在IL(将与IL被更新):

IL_0000: nop 
    IL_0001: newobj  instance void SimpleDataPlayGround.Foo::.ctor() 
    IL_0006: stloc.2 
    IL_0007: ldloc.2 
    IL_0008: ldstr  "Baaz" 
    IL_000d: callvirt instance void SimpleDataPlayGround.Foo::set_Bar(string) 
    IL_0012: nop 
    IL_0013: ldloc.2 
    IL_0014: stloc.0 
    IL_0015: ldstr  "Now the old way sugar" 
    IL_001a: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_001f: nop 
    IL_0020: newobj  instance void SimpleDataPlayGround.Foo::.ctor() 
    IL_0025: stloc.1 
    IL_0026: ldloc.1 
    IL_0027: ldstr  "Baaz" 
    IL_002c: callvirt instance void SimpleDataPlayGround.Foo::set_Bar(string) 
    IL_0031: nop 
    IL_0032: ret 

UPDATE

OK,乔恩的意见后,很明显,有一个略有差异。但至于这个问题 - 主要是性能的影响 - 只有Jon指出,如果一个对象被用于自己的重新创建,这可能很重要。

+0

你的IL表明有一个区别 - 在“旧方法”中,变量在属性设置器之前被分配*。在对象初始化形式中,“ldloc.2,stloc.0”表示将临时变量复制到“f”中。查看我的答案了解更多详情。 –

+0

谢谢乔恩。你的洞察力永远是新鲜的。我可以看到你现在的意思。 – Aliostad

3

这两个不是一样。对象初始化形式转化为更多的东西像这样的(至少在逻辑上,我相信有一些箱子所在的C#编译器将只使用一个变量):

Employee tmp = new Employee(); 
tmp.Name = "Bob"; 
Employee currentUser = tmp; 

,如果你是这一点尤为重要有史以来改变变量的值。例如:

Employee currentUser = new Employee { Name = "Bob" }; 

currentUser = new Employee { Name = currentUser.Name + "Foo" }; 

这里的结果将与“BobFoo”的名雇员,只是“富”,这是你会得到什么,如果在之前发生的赋值给变量财产制定者。

在读取变量的当前值的其他情况下,这可能是重要的,例如,在财产制定者。不太可能,但可能。

有关详细信息,请参阅第7.6.10.2节,其中以“不可见和不可访问的临时变量”的形式明确指定。

相关问题