C# 为什么Array.Length是int而不是uint

C# 为什么Array.Length是int而不是uint,c#,.net,int,uint,C#,.net,Int,Uint,为什么Array.Length是int,而不是uint。这让我很烦恼(只是有一点),因为长度值永远不能为负 这也迫使我在自己的类中使用int作为length属性,因为 指定一个int值,这需要显式转换 所以最终的问题是:无符号int(uint)有什么用处吗?甚至微软似乎也不使用它们。通常,整数值是有符号的,除非您明确需要无符号值。这只是他们的使用方式。我可能不同意这个选择,但事实就是这样 目前,对于典型的内存限制,如果您的数组或类似的数据结构需要UTI32长度,则应该考虑其他数据结构。 对于字节

为什么
Array.Length
是int,而不是
uint
。这让我很烦恼(只是有一点),因为长度值永远不能为负

这也迫使我在自己的类中使用int作为length属性,因为 指定一个int值,这需要显式转换


所以最终的问题是:无符号int(
uint
)有什么用处吗?甚至微软似乎也不使用它们。

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

目前,对于典型的内存限制,如果您的数组或类似的数据结构需要UTI32长度,则应该考虑其他数据结构。


对于字节数组,Int32将为您提供2GB的值

无符号int不符合CLS,因此将该属性的使用限制为那些实现了
UInt
的语言

请看这里:

框架1.1

框架2.0


我认为这可能还需要在较低的层次上简化事情,因为Array.Length当然会在某个时候被添加到负数,如果Array.Length是无符号的,并添加到负数int(2的补码),可能会有混乱的结果。

看起来似乎没有人提供“最终问题”的答案

我认为未签名int的主要用途是提供与外部系统(p/Invoke等)的更简单接口,并满足各种语言移植到.NET的需要。

原因很多:

  • uint不符合CLS,因此使内置类型(数组)依赖于它会有问题
  • 最初设计的运行时禁止堆上任何占用2GB以上内存的对象。由于小于或等于此限制的最大大小的数组将是新字节[int.MaxValue],因此人们无法生成正但非法的数组长度。
    • 请注意,虽然标准长度为int,但此限制已被取消
  • 历史上C语言继承了它的许多语法和惯例,从C和C++中继承。在这些数组中,指针只是简单的算术运算,所以负数组索引是可能的(尽管通常是非法和危险的)。由于许多现有代码假定数组索引是有符号的,因此这可能是一个因素
  • 另一方面,在C/C++中对数组索引使用有符号整数意味着与这些语言和非托管函数的互操作无论如何都需要在这些情况下使用INT,这可能会由于不一致而混淆
  • BinarySearch实现(许多算法的一个非常有用的组件)依赖于能够使用int的负范围来指示未找到该值插入该值以保持排序的位置
  • 在数组上操作时,可能需要对现有索引进行负偏移。如果您使用的偏移量超过了使用unit的数组的开头,那么环绕行为将使您的索引可能合法(因为它是正的)。如果使用int,结果将是非法的(但安全的,因为运行时将防止读取无效内存)

如果堆上的任何内容都不能超过2Gb,那么几乎所有长度为int.MaxValue的数组都是非法的,因为大多数类型都大于1字节。事实上,((uint)(int.MaxValue))+1肯定是错误的。int本身远不是完美的,但是事物的平衡使得使用int作为类型是合法的。从一个显式的ArrayIndex类型(基本上是size_t)开始,它可以根据需要干净、安全地转换为int,这可能会使将来更容易真正地使用,允许将来使用>2GB的阵列,而不那么麻烦。但是语用学认为java也有同样的问题,所以为什么要冒险呢?这是非常有用的。在.NET 4的Windows通信基础上,对于代码<最大值>最大值> /COD>和<代码> MyByTeExpRead 最大的值是2147483647。连接点…只是想补充一下,在不安全的上下文中,C#指针算法也允许负索引。请看下面的例子:“但事情就是这样。”——不,事情从来都不是这样的。设计决策总是要做出的,问为什么总是值得的。一个人可以从正反两方面学到一些东西,或者让设计师(在某些情况下)参与到关于正反两方面的讨论中。总是问问题!:)尽管有下面提到的问题,我认为它应该改为UInt。@alan2在这里做这样的更改会破坏那里几乎所有的代码,所以如果你问我,它不会发生!当连接多个较小的值以生成较大的值时,无符号类型是必不可少的。可以通过计算
(高部分请给出一个例子?
uint lenght=3;int x=-4;Console.WriteLine(x+lenght);
生成-1就可以了。