2011-09-03 39 views
19

當在一個類中定義了一切時,C#中如何存在全局函數?我在MSDN讀取的OpCodes.Call的文檔,並驚訝地發現以下字眼,C#中如何存在全局函數?

元數據令牌攜帶足夠的信息,以確定該呼叫是否是一個靜態方法,實例方法,虛擬方法, 或全局函數。

全局函數?它存在於C#中嗎? (它絕對不涉及static方法,因爲它與全局函數一起明確列出)。

+3

OpCodes.Call不是針對C#,但對CLR –

+0

如果我們告訴你,我們不得不KIL你。 ;)認真的說,全局變量是不好的 - 不要去實現它們。 – TrueWill

+0

爲什麼全局函數/方法的定義不好? –

回答

15

您不能在C#中使用全局函數,它只是不屬於該語言的一部分。你必須在你選擇的某個類上使用靜態方法來獲得類似的功能。

但是C#並不是唯一使用CLR的語言。可以編寫託管C++,它可以具有全局功能。

+1

但是我聽說過,當你編寫Managed C++(或C++/CLI)時,所有的全局函數都被壓入由編譯器生成的靜態類中。實際上,沒有全球功能的概念。 – Nawaz

+0

這可能發生在封面下,我不確定。如果您找到該鏈接,請將其發佈。還有其他語言......我沒有做完整的調查。 –

+7

@Nawaz:這是一個與本次討論沒有密切關係的實現細節。要點在於'System.Reflection.Emit'屬於IL,而不屬於C#或託管C++或任何其他編譯爲IL且位於.NET Framework之上的語言。 Managed C++中是否存在全局函數或它們如何實現並不重要。重要的是,在解釋IL的虛擬或真實機器中,存在全局函數的概念,並且可以使用System.Reflection.Emit.OpCodes.Call來發出可以調用全局函數的IL操作碼。 – jason

3

我想是的事情是,這是IL注入操作,但IL是而不是絕對只有關於C#。換句話說,它支持支持全球功能的語言。

+0

例如?... – Nawaz

+1

@Nawaz:我相信這是關於像動態語言一樣的,例如IronPython,F#(不太確定)。一個有趣的東西可以在這裏找到方法動態生成:http://msdn.microsoft.com/en-us/library/system.reflection.emit.modulebuilder.createglobalfunctions(VS.95).aspx – Tigran

3

您提到的文檔是.net。 C#不支持全局函數,但.net可以。

+1

究竟如何?請在你的回答中更慷慨。 :-)(我剛接觸.Net)。 – Nawaz

+2

.net是一個平臺。 C#編譯器存在於該平臺之上,但.net被設計爲服務於C#以上。 C#設計人員選擇不在該語言的設計中考慮全局功能,但在.net上構建的其他語言可以選擇這樣做。事實上,.net充滿了不通過個別語言暴露的功能。 –

7

因爲System.Reflection.Emit.OpCodes.Call不是關於C#的。這關乎發射IL操作碼。在IL中,有些功能在C#中不可用。全球功能就是這些功能之一。

3

C#不支持MSIL的所有功能。全球職能就是其中之一。 VB.Net,F#,IronPython或其他一些語言來使用這些和其他功能,這些功能並不是由C#編譯器生成的。

+0

他們可能,他們可能不會。沒關係。關鍵是IL支持它們,因此解釋IL的虛擬或真實機器支持它們。編譯爲IL的其他語言是否執行,或者如果這些語言的編譯器將這些全局函數轉換爲編譯後的IL中的全局函數,則無關緊要。 – jason

3

我只是覆蓋我以前的答案...

下面是每個看起來像IL DASM與相關的代碼:

// Static Method 
IL_0001: call  void testapp.Form1::Test() 

// Instance Method 
IL_0001: call  instance void testapp.Form1::Test() 

// Virtual Method 
IL_0001: callvirt instance void testapp.Form1::Test() 

// Global Function 
IL_0000: call  void testapp.Test() 

因此,要回答你的問題,不存在一種在C#的最後一種方法中生成元數據標記的直接方式。我不得不在C++中創建最後一個。

11

在構建2014會議上曾宣佈,從羅斯林起,您可以通過using TypeName;指令匯入類型的靜態方法,使的,而不必使用System.Math.Min(...)你可以這樣做:

using System.Math; 
... 
var z = Min(x,y); 

注:由發行時本變成了:

using static System.Math; 
+0

+1。偉大的信息! – Nawaz

+0

儘管在原始問題的意義上,這仍然不是一個全球性的功能;它是句法速記,省去了輸入「System.Math.Min」或「Math.Min」的麻煩。就運行時而言,它仍然只是類「System.Math」上的靜態函數 – jimmyfever