2013-05-28 141 views
3

以下代碼片段之間有什麼區別?聲明實例差異

Form1 form1 = new Form1(); 

Form1 form1; 

public Class1() 
{ 
    form1 = new Form1(); 
} 
+5

前者是內聯初始化,後者是構造函數中的初始化。請參見:[最佳實踐:在構造函數或聲明中初始化類字段?](http://stackoverflow.com/questions/24551/best-practice-initialize-class-fields-in-constructor-or-at-declaration) –

+2

只要初始化發生在變量被使用之前,實際上沒有太大的區別。但是,在聲明中初始化時,確保在初始化之前不能嘗試使用該對象。 – tinstaafl

回答

4

在你的具體的例子,沒有任何區別。兩者都將被編譯爲相同的IL。 這只是一個偏好/風格的問題。

一般來說,所不同的是以下內容:

第一個版本不能訪問此類,第二版罐的其他實例成員。

1

在第一個中,您只是在類中初始化變量,然後在第二個中初始化構造函數中的變量。

這兩者幾乎沒有任何性能折衷。 除了語義上的簡單性,它的選擇,以及你的前進方向。

閱讀更here

0

在聲明Form1類型的引用,直到您在構造函數中使用new關鍵字inialize它不包含任何東西(沒有對象),第二個選項。在第一個選項中,您立即聲明並初始化。

4

不同之處在於,您可以精確控制第二種情況下初始化發生的時間。

有了這種內聯初始化,你不能依賴於一個初始化另:

int a = 42; 
int b = a; // not definitely known to have a value yet 

當你在構造函數初始化它們,你有過爲了控制它們運行:

int a, b; 

public Class1() { 
    a = 42; 
    b = a; 
} 

除此之外,沒有任何真正的區別。內聯初始化將由編譯器放置在構造函數中,因爲這是可以完成這種初始化的唯一位置。

0

第一個片段的結果是form1將包含類Form1的新實例。

第二個片段不會創建一個新的實例,只會有一個未初始化的變量(它會被初始化爲null)。

結合這將是:

Form1 form1; 

public Class1() 
{ 
    form1 = new Form1(); 
}   

現在代碼fragement上面是一個類的一部分,當你創建一個這樣的類的實例,它會調用Class1的,導致在Form1被分配到一個新的實例的Form1。例如:

class Class1 
{ 
    Form1 form1; 

    public Class1() 
    { 
     form1 = new Form1(); 
    }   
} 

c = Class1(); 

c將調用Class1的構造函數,該函數調用新的Form1()並將其分配給form1。

0

根據的C#特定語言規範10.11。3

變量初始化器轉換爲賦值語句,這些賦值語句在調用基類實例構造函數之前執行。這種排序確保所有實例字段在執行任何有權訪問該實例的語句之前由其變量初始化器初始化。

在你的具體例子中,沒有例子。然而,如果我們在這裏本說明書中運行的一個示例:

using System; 

class A { 
    int x = 1; 
    int y; 
    public A() { 
     y = -1; 
    } 
} 

當新A()被調用的出把x = 1且y = 0的(缺省值),直到構造被執行。