2017-02-15 72 views
12

根據「C#語言規範5.0版」中的「10.12靜態構造函數」一節,靜態構造函數可以標記爲「extern」修飾符,在這種情況下,它被稱爲外部靜態構造函數C#中外部靜態構造函數的用途是什麼?

普通(非外部)靜態構造函數是衆所周知的。它們用於初始化靜態字段和屬性。

外部靜態方法通常用於通過P/Invoke調用本地函數。

而且我也知道相當深奧的extern構造函數(另請參閱this question)。例如,String類有幾個這樣的declarations,這些構造函數是由運行時實現的。

但是外部靜態構造函數的任何真正用法?我搜遍了coreclr repo,一無所獲。語言規範無法描述一些在野外從未使用過的構造。或者可以嗎?我猜:C#有外部靜態構造函數,因爲CLR支持它們(原則上)。

+0

我想你會在10.6(方法)到10.13(析構函數)的第10節的每個小節中找到非常相似的文本塊。如果沒有別的,至少它*一致*。 –

+1

'extern'唯一的做法是將該方法的RVA設置爲0.運行時需要確定其餘部分。另見http://stackoverflow.com/q/38015024/。語言規範沒有什麼理由禁止這樣做,因爲編譯器的工作是微不足道的(取而代之的是更多的工作)。此外,由於構造函數不能標記爲'DllImport',因此實現此類方法的唯一方法是使用'MethodImplOptions.InternalCall',因此運行時是唯一可能的消費者,因此明確禁止它是更不有趣的。 –

+0

至於爲什麼他們沒有被實際使用,那是在猜測的領域,但如果我是一個CLR實現者,我更願意做我的靜態初始化,以便輕鬆預測點,而不是依賴相當神祕的規則用於初始化靜態類型。無論如何,所有這些代碼都會回到運行時,所以它只會讓我的工作更加困難。 –

回答

1

從MSDN:

當構造函數聲明包含extern修飾符,所述 構造被認爲是外部的構造。由於外部構造函數聲明沒有提供實際的實現,因此其構造函數體由分號組成。

...

看來我們不能想到一個很好的理由使用這個聲明,它肯定正確的。 但是當你進一步挖掘你意識到有一個動態組裝的整個世界或 - 代碼生成。

如果您要爲.NET平臺開發編譯器,那麼您可能需要一些小小的解決方案,就像C#編譯器使用的那樣。我可以認識到,一些核心實現使用extern構造函數,這是爲了良好的設計原因而在其他地方實現的。