2013-11-24 84 views
7

在研究CLI的內部,我注意到,可能的是類型簽名來指定數組邊界例如,代替具有(在編譯時。):編譯時數組邊界

Byte[,]

我們可以有:

Byte[1...100,1...]

如果我沒有記錯的話,不可能在C#或C++/CLI喜歡後者實際聲明類型。此外,ECMA-335指示:

VES爲每個可區分的數組類型創建一個數組類型。一般來說,數組類型只能根據元素的類型和級別進行區分。

公共語言規範(CLS)強加了許多限制,包括:

只有一個事實,即一個項目是一個數組,該數組的元素類型應是 區分需要重載。

因此,對編譯時數組邊界的支持似乎存在於CLI的最低層而不是其他地方。這導致我想知道:

  • 什麼時候會在實踐中創建/遇到包含此信息的類型簽名? 做的有沒有.NET語言?編輯:有些語言可能通常使用基於一個數組 - 但他們是否將其編碼到類型簽名?

  • 哪裏的CLI實際上使用如果目前這一信息? (這尤其感興趣的是,我爲我設計CLI實現。)

據我所看到的,任何陣列中創建或者使用的載體爲在newarr字節碼指令,或Array.CreateInstance一般情況。這兩種機制都不接受這個陣列本身的類型簽名,所以創建它似乎不能使用這些信息。

從理論上講,這些信息可以通過內聯高效機器代碼來優化數組訪問來計算地址。但是,ldelem和朋友只能訪問簡單的向量;多維數組訪問需要一個方法調用,這讓我認爲這樣的優化可能不會發生。

我不得不認爲這個機制有一些目的,爲了使它成爲一個國際標準,但我沒有真正看到它。

+0

作爲評論,因爲這只是我的個人猜想:某些語言允許自定義數組起始索引,而不是C#所建模的基於C的語言。儘管如此CLI仍然支持這些自定義開始索引,並支持基於Pascal語言的編譯器,如[Oxygene](http://www.remobjects.com/oxygene/)或[A#](http://asharp.martincarlisle.com/)可能很好地發射那種陣列。基於非零的數組實際上可以在C#中用[Array.CreateInstance]的此重載反射來創建(http://msdn.microsoft.com/zh-cn/library/x836773a%28v=vs.110% 29.aspx)。 –

+0

哦,至少當['Array.GetLowerBound'方法](http://msdn.microsoft.com/en-us/library/system.array.getlowerbound%28v)時,CLI肯定會使用這些信息= vs.110%29.aspx)被調用。 –

+0

@ORMapper:我有一種感覺可能會有一些語言會使用這種邊界..但是,請注意,您提到的'Array.CreateInstance'重載實際上將邊界作爲參數,因此_not_不會使用_type簽名_ 。同樣,'Array.GetLowerBound'正在訪問有關_runtime instance_的信息。我知道在_runtime_可以直接使用非零基 - 我關心的更多的是爲什麼可以將這些信息靜態地包含在_type簽名_中。 – Kevin

回答

1

此信息僅出現在數組類型的簽名中,在運行時不可訪問數組對象成員。對於認爲具有不同邊界的數組的語言來說,這是非常重要的,Pascal語言就是一個例子。它將array[1..10] of integer類型的變量視爲不同且與array[1..11] of integer類型的變量不兼容。

+0

既然你這樣說,我能夠在規範中找到一些引號來增加一些清晰度。如果我將它們添加到您的答案,請介意一下。 – Kevin

+0

當然,編輯答案是完全可以接受的。 –