2012-09-15 18 views
0

畢竟指針是值類型。這就是他們所指的 - 是參考類型。這是正確的還是什麼?如何在CLR棧上「引用」實現方式的引用類型?

+0

(至少在C中),指針具有基於類型的單獨大小。不知道MicrosoftJava(C#)如何處理這個問題,但使用指針存儲大量信息聽起來效率不高,即使是微軟也是如此。 –

+0

@GungFoo實際上只有在非常特殊的情況下才會在C++中指向彼此不同的大小;大多數指針是相同的大小。 –

+1

@seth 1.我正在談論C;)2.指針不能保證具有相同的大小..它們在platform1上的大小可能相同,但這並不說明有關platform2的一些問題。這就是爲什麼如果你將一個void指針轉換爲不同類型的指針,你會得到一個警告。 –

回答

1

是的,這是正確的。所有局部變量都存儲在堆棧中,無論它們是什麼類型(值類型或引用類型)。當你創建一個引用類型的變量時,它將被保存在堆棧上,當你實例化一個對象並將其分配給該變量時,一些內存將被分配到堆上,該堆將被存儲在堆棧上的變量引用。

+0

並非所有本地變量都存儲在堆棧中。由閉包捕獲的局部變量在閉包類中創建爲類級變量。 – Enigmativity

+0

@Enigmativity - 請詳細說明! – MontyPython

+0

@MontyPython - 我添加了一個例子作爲答案 - http://stackoverflow.com/a/12451933/259769。 – Enigmativity

1

參考文獻呢?引用既不是值類型也不是引用類型的實例,但它們是值。他們必須存儲在某個地方。他們是在棧還是在堆上?爲什麼沒有人會談論他們?僅僅因爲他們在C#類型系統中沒有類型就沒有理由忽略它們。

在過去,我通常推回這個神話的方式是說,真正的聲明應該是「在微軟在桌面CLR上執行C#,當值爲時,值類型被存儲在堆棧上一個局部變量或臨時變量,它不是lambda或匿名方法的閉合局部變量,並且方法體不是迭代器塊,並且抖動選擇不註冊該值。「

得到了博客的答案。這裏的鏈接 - Eric Lippert's Blog

+1

這個回覆讓我感到困惑......也許*更仔細的選擇* Eric的[好]文章的摘錄或摘要將清除一切。此外,使用'>'引用(和因此屬性)更好的摘錄。 – 2012-09-15 23:57:48

+0

此外,雖然文章是一個很好的閱讀,但這個問題明確要求引用類型,所以引入值類型只是混淆了事物,因爲值類型有時被「解除」,但有時候不是。這與引用類型不同這些被問到)。 – 2012-09-15 23:59:57

0

作爲對OP的評論的迴應,下面是一個局部變量變爲類級變量的例子。

如果我開始使用此代碼:

void Main() 
{ 
    var x = 42; 
    Func<int> f =() => x; 
    var y = f(); 
} 

編譯器把它變成這樣的代碼:

void Main() 
{ 
    var CS$<>8__locals2 = new <>c__DisplayClass1(); 
    CS$<>8__locals2.x = 42; 
    Func<int> f = CS$<>8__locals2.<Main>b__0; 
    var y = f(); 
} 

而且它會創建下列<>c__DisplayClass1類:

[CompilerGenerated] 
private sealed class <>c__DisplayClass1 
{ 
    public int x; 

    public int <Main>b__0() 
    { 
     return this.x; 
    } 
} 

我爲了清楚起見,我已經做了一些清理代碼的工作。