2008-08-08 117 views
77

爲什麼Array.Length是int,而不是uint。這讓我感到困擾(只是一點點),因爲長度值永遠不會爲負。爲什麼Array.Length是一個int,而不是一個uint

這也迫使我用我自己的類的長度屬性的int,因爲當你 指定一個int值,這需要顯式轉換...

所以最終的問題是:有沒有用於一個無符號整數(uint)?即使微軟似乎也不會使用它們。

+0

儘管下面提出的問題,我認爲它應該改變爲UInt。 – alan2here 2011-11-28 23:43:24

+1

@alan2這樣的改變會破壞幾乎所有的代碼,所以如果你問我,它就不會發生! 「 – Peter 2012-08-23 14:38:34

回答

0

通常,對整數值進行簽名,除非您明確需要無符號值。這只是他們使用的方式。我可能不同意這種選擇,但事實就是如此。如果你的數組或類似的數據結構需要一個UInt32長度,你應該考慮其他數據結構。如果你的數組或類似的數據結構需要一個UInt32長度,你應該考慮其他數據結構。

隨着字節數組,的Int32會給你2GB值

+13

」但這只是它的方式。「 - 不,事情從來就不是這樣。總是有一個設計決策正在制定中,並且爲什麼總是要付出代價。人們可以從正反兩方面學到一些東西,或者讓設計師(在某些情況下)參與關於它們的討論。始終提出問題! :) – 2009-06-25 10:54:38

1

我認爲它也可能與更簡單的事情有關,因爲Array.Length當然會在某些時候被添加到負數,如果Array.Length是無符號的,並且被添加到負int(2的補充),可能會有混亂的結果。

+0

請舉個例子嗎? `uint lenght = 3; int x = -4; Console.WriteLine(x + lenght);`yield -1就好了。 – 2014-06-12 22:46:01

1

看起來沒有人提供了「最終問題」的答案。

我相信主要使用unsigned int是爲了提供與外部系統(P/Invoke之類)更容易的接口,並且涵蓋了被移植到.NET的各種語言的需求。

+0

當連接多個較小值以產生較大值時,無符號類型是必不可少的。通過計算`(HighPart << 16)+ LowPart`,可以將兩個UInt16組合成一個UInt32,並且可以通過`(Uint16)(Value >> 16)`和`(Uint16)將Value分解爲兩個UInt16 &65535)`。如果LowPart必須是簽名類型,這樣的操作將非常不方便。如前所述,簽名類型和未簽名類型之間的交互往往是令人困惑和有問題的。無符號類型應該在很多方面被認爲是他們自己的世界。 – supercat 2013-02-03 17:45:16

45

許多原因:

  • UINT不符合CLS,從而使內置型(陣列)依賴於它本來問題
  • 作爲最初設計運行時禁止在堆上佔用任何對象超過2GB的內存。由於最大大小的數組小於或等於此限制將是新的字節[int.MaxValue],因此人們可能會產生積極但非法的數組長度令人費解。
  • 從歷史上看,C#從C和C++中繼承了它的大部分語法和約定。在那些數組中只是指針算術,所以負數組索引是可能的(儘管通常是非法和危險的)。由於許多現有的代碼假定數組索引被簽名,所以這將是一個因素
  • 在相關說明中,在C/C++中對數組索引使用帶符號整數意味着與這些語言和非託管函數進行互操作需要使用無論如何都會在這些情況下進行整合,這可能會由於不一致而混淆。
  • BinarySearch實現(許多算法中非常有用的組件)依賴於能夠使用int的負範圍來指示未找到該值這樣一個值應該插入以保持的位置排序。
  • 在數組上操作時,您可能希望獲取現有索引的負偏移量。如果您使用的偏移量會使您通過使用單位的數組的開始,那麼環繞行爲會使您的索引可能合法(因爲它是正數)。如果使用int,結果將是非法的(但安全,因爲運行時會防止讀取無效內存)
相關問題