2014-09-29 31 views
1

這只是一種語言好奇而不是問題。IEnumerable,.ElementAt和C#中的無符號/有符號索引?

IEnumerable的ElementAt()方法接受整數以獲取可枚舉集合的第N個元素。

例如

var list = new List<char>() { 'a', 'b', 'c' }; 
var alias = list.AsEnumerable(); 
int N = 0; 
alias.ElementAt(N); //gets 'a' 

都好,但是爲什麼不ElementAt的()接受無符號整數(UINT)? 例如

uint N = 0; 
alias.ElementAt(N); //doesn't compile 

我可以理解爲什麼ElementAt的可以接受的整數允許負指數(如Python允許負指數,其中列表[-1]指最後一個元素),因此是很有意義有接受這些語言負索引即使C#沒有使用它們。

但我不能完全看到拒絕無符號整數的原因,如果任何無符號整數更好,因爲它保證索引不會是負數(所以只需要檢查範圍的上限)。

我能想到的最好的事情可能是CLR團隊決定對帶符號整數進行標準化,以允許具有負指數的其他語言(例如Python)使用相同的代碼並確保範圍跨語言一致。

有沒有人有更好/權威的解釋,爲什麼.ElementAt()不允許unsigned int?

-Marcin

+3

無符號整數不[CLS兼容](http://msdn.microsoft.com/en-us/library/12a7a7h3%28v=vs 0.110%29.aspx)。 – 2014-09-29 04:05:23

+0

謝謝。打開了我的眼睛,以符合CLS。 http://stackoverflow.com/questions/6325/why-are-unsigned-ints-not-cls-compliant可能對任何想知道這一切的人都有用。 – Marcin 2014-09-29 04:17:53

回答

1

真正的原因是,.NET數組可以是非零爲主,即使C#語言不支持,宣佈陣列。您仍然可以使用Array.CreateInstance Method (Type, Int32[], Int32[])創建它們。 請注意帶有星號的已創建對象(System.Int32 [*])的類型的特殊名稱。

列表在內部使用數組實現,使用不同類型的索引是不現實的。

此外,Count屬性通常參與數組指數計算,其中部分結果可能是負數。在表達式中混合類型會很麻煩並且容易出錯。

具有不能表示負指數的類型將無助於錯誤檢測。 與unchecked操作一起使用自動裁剪不會修復應用程序中的邏輯數組索引計算錯誤。

下面的例子示出了基於負數組操作C#:

var negativeBasedArray = Array.CreateInstance(typeof(Int32), 
    new []{2}, // array of array sizes for each dimension 
    new []{-1}); // array of lower bounds for each dimension 
Console.WriteLine(negativeBasedArray.GetType()); // System.Int32[*] 
negativeBasedArray.SetValue(123, -1); 
negativeBasedArray.SetValue(456, 0); 
foreach(var i in negativeBasedArray) 
{ 
    Console.WriteLine(i); 
} 
// 123 
// 456 
Console.WriteLine(negativeBasedArray.GetLowerBound(0)); // -1 
Console.WriteLine(negativeBasedArray.GetUpperBound(0)); // 0