C#中的IEnumerable,.ElementAt和unsigned / signed索引?

时间:2014-09-29 03:58:31

标签: c# .net clr ienumerable

这只是一种语言好奇而不是问题。

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)? e.g。

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

我可以理解为什么ElementAt可以接受整数来允许负指数(例如Python允许负数索引,其中list [-1]指的是最后一个元素),因此对那些使用它们的语言接受负指数是有意义的即使C#没有。

但是我不能完全看到不允许无符号整数的推理,如果有任何无符号整数更好,因为它保证索引不会是负数(因此只需要检查范围的上限)。 / p>

我能想到的最好的事情可能是CLR团队决定对有符号整数进行标准化,以允许其他具有负索引的语言(例如Python)使用相同的代码,并确保范围在各种语言中保持一致。

有没有人对.ElementAt()不允许无符号整数的原因有更好/权威的解释?

-Marcin

1 个答案:

答案 0 :(得分:1)

真正的原因是.NET数组可以是非零的,即使C#语言不支持声明这样的数组。您仍然可以使用Array.CreateInstance Method (Type, Int32[], Int32[])创建它们。 请注意创建的对象类型的特殊名称(System.Int32 [*]),其中带有星号。

List是在内部使用数组实现的,使用不同类型进行索引是不切实际的。

此外,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