2011-08-07 168 views

回答

1

嚴格地說,它取決於代碼的位置。

如果代碼是常規函數/方法,它將隻影響堆棧。對堆沒有任何影響,因爲尚未構建MyClass對象。

假設MyClass是一個類(即引用類型),聲明將在棧上保留足夠的空間來容納對MyClass對象的引用。

這兩個聲明略有不同 - 第一個聲明沒有被初始化,所以任何嘗試訪問oMyClass1之前它被設置爲某些東西會給編譯器錯誤。第二個是初始化的,所以你不會遇到編譯器錯誤[雖然如果你在設置它引用一個實際的對象之前訪問了oMyClass2的方法或屬性,你會得到一個運行時錯誤,與oMyClass2 = new MyClass();]。

如果代碼是一個類聲明中:

class Fred { 
    MyClass oMyClass1; 
    MyClass oMyClass2 = null; 
} 

那麼它只會在Fred構造函數中執行。在構造函數被調用之前,空間(對於Fred對象,包括兩個MyClass引用的空間)已經在堆上分配了。這兩行代碼實際上不起作用,因爲空格已經被初始化爲空。

如果它在一個結構聲明內,只會在堆棧上(如果結構是本地的)或全局變量內存(如果結構是靜態的)產生相似效果。 [雖然,公平地說,我有點不確定在C#中靜態分配的位置 - 我只是假設它以類似於C++的方式完成]

+0

正如我已經在一個現在被刪除的答案中所說的,不是類成員的值類型的實例*並不總是存儲在堆棧中*。如果它們被lambda表達式或迭代器塊捕獲,它們將被存儲在堆上。 –

+0

引用只會在堆棧上分配,如果它們是本地人。如果他們是班級成員,他們將會堆積如山。 –

+0

@Frédéric值得詳細說明的是,如果他們被拉姆達捕獲,他們不再是「本地人」。它們將被轉換爲對閉包類(即包裝對象)的屬性的引用。閉包坐在堆上。 –

3

我的疑問是如何將上述兩行影響內存(堆棧&堆)。

信息不足,兩種可能性:

  1. 他們是局部變量。在這種情況下,這兩行在堆棧上(無論何時執行該方法多長時間)進行2次相同的分配(參考,總是32/64位)。在堆上沒有分配。

  2. 它們是類或結構中的字段。在這種情況下,這兩行分配創建時實例中引用的大小。該實例可以在堆棧上(當它們是struct成員時)或堆(類成員)上分配。

+0

+1編輯之後,在點2中區分結構和類。 –