【问题标题】:IEnumerable, .ElementAt and unsigned/signed indices in C#?C# 中的 IEnumerable、.ElementAt 和无符号/有符号索引?
【发布时间】:2023-04-05 03:54:01
【问题描述】:

这只是对语言的好奇而不是问题。

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 允许负索引,其中 list[-1] 指的是最后一个元素),因此对于那些使用负索引的语言来说,接受负索引是有意义的即使 C# 没有。

但我不太明白禁止无符号整数的原因,如果有的话,无符号整数更好,因为它保证索引不会为负(因此只需要检查范围的上限)。

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

对于为什么 .ElementAt() 不允许无符号整数,有没有人有更好/权威的解释?

-马辛

【问题讨论】:

标签: c# .net clr ienumerable


【解决方案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

【讨论】:

    猜你喜欢
    • 2011-10-11
    • 2015-01-24
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 2011-04-09
    • 2012-09-30
    • 2011-11-25
    相关资源
    最近更新 更多