2011-10-24 149 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節,其中以「不可見和不可訪問的臨時變量」的形式明確指定。

相關問題