关于c#:为什么Array.Length是int而不是uint

关于c#:为什么Array.Length是int而不是uint

Why is Array.Length an int, and not an uint

本问题已经有最佳答案,请猛点这里访问。

为什么Array.Length是int而不是uint。 这使我感到困扰(一点点),因为长度值永远不能为负。

这也迫使我在我自己的班级上使用int作为长度属性,因为当您
指定一个int值,这需要显式转换...

因此,最终的问题是:unsigned int(uint)有什么用吗? 甚至微软似乎都不使用它们。


Unsigned int不符合CLS,因此会将属性的使用限制为那些确实实现了UInt的语言。

看这里:

框架1.1

Introduction to the .NET Framework Class Library

框架2.0

.NET Framework Class Library Overview


很多原因:

  • uint不符合CLS,因此使依赖于它的内置类型(数组)会出现问题
  • 最初设计的运行时禁止堆上的任何对象占用2GB以上的内存。由于小于或等于此限制的最大大小的数组将是新的byte [int.MaxValue],因此人们会感到困惑,因为它们能够生成正数但非法的数组长度。

    • 请注意,尽管保留了标准的int长度,但在4.5版本中已删除了此限制。
  • 从历史上看,C#继承了C和C ++的大部分语法和约定。在那些数组中,只是指针算术运算,因此可以进行负数组索引(尽管通常是非法和危险的)。由于许多现有代码假定数组索引已签名,因此这将是一个因素
  • 值得一提的是,在C / C ++中对数组索引使用带符号整数意味着在这些情况下与这些语言和非托管函数的互操作无论如何都需要使用int,这可能会因不一致而造成混淆。
  • BinarySearch实现(许多算法中非常有用的组件)依赖于能够使用int的负数范围来表示未找到该值以及应插入该值的位置以保持排序。
  • 在数组上进行操作时,您可能希望对现有索引取负值。如果您使用的偏移量使您使用单位超过了数组的开头,那么回绕行为将使您的索引可能合法(因为它是正数)。带有int的结果将是非法的(但很安全,因为运行时将防止读取无效的内存)


似乎没有人提供对"最终问题"的答案。

我相信无符号整数的主要用途是使与外部系统(P / Invoke等)的接口更容易,并满足移植到.NET的各种语言的需求。


我认为这也可能与简化底层操作有关,因为如果Array.Length是无符号的,则Array.Length当然会在某个时候添加到负数,并添加到负int(二进制补码) ,结果可能会混乱。


通常,整数值是带符号的,除非您明确需要一个无符号的值。这只是它们的使用方式。我可能不同意这种选择,但这就是事实。

目前,在当今典型的内存限制下,如果您的数组或类似数据结构需要UInt32长度,则应考虑其他数据结构。

使用字节数组,Int32将为您提供2GB的值


推荐阅读