2008-08-08 105 views
77

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

这也迫使我用我自己的类的长度属性的int,因为当你 指定一个int值,这需要显式转换...

所以最终的问题是:有没有用于一个无符号整数(uint)?即使微软似乎也不会使用它们。

+0

尽管下面提出的问题,我认为它应该改变为UInt。 – alan2here 2011-11-28 23:43:24

+1

@alan2这样的改变会破坏几乎所有的代码,所以如果你问我,它就不会发生! “ – Peter 2012-08-23 14:38:34

回答

0

通常,对整数值进行签名,除非您明确需要无符号值。这只是他们使用的方式。我可能不同意这种选择,但事实就是如此。如果你的数组或类似的数据结构需要一个UInt32长度,你应该考虑其他数据结构。如果你的数组或类似的数据结构需要一个UInt32长度,你应该考虑其他数据结构。

随着字节数组,的Int32会给你2GB值

+13

”但这只是它的方式。“ - 不,事情从来就不是这样。总是有一个设计决策正在制定中,并且为什么总是要付出代价。人们可以从正反两方面学到一些东西,或者让设计师(在某些情况下)参与关于它们的讨论。始终提出问题! :) – 2009-06-25 10:54:38

1

我认为它也可能与更简单的事情有关,因为Array.Length当然会在某些时候被添加到负数,如果Array.Length是无符号的,并且被添加到负int(2的补充),可能会有混乱的结果。

+0

请举个例子吗? `uint lenght = 3; int x = -4; Console.WriteLine(x + lenght);`yield -1就好了。 – 2014-06-12 22:46:01

1

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

我相信主要使用unsigned int是为了提供与外部系统(P/Invoke之类)更容易的接口,并且涵盖了被移植到.NET的各种语言的需求。

+0

当连接多个较小值以产生较大值时,无符号类型是必不可少的。通过计算`(HighPart << 16)+ LowPart`,可以将两个UInt16组合成一个UInt32,并且可以通过`(Uint16)(Value >> 16)`和`(Uint16)将Value分解为两个UInt16 &65535)`。如果LowPart必须是签名类型,这样的操作将非常不方便。如前所述,签名类型和未签名类型之间的交互往往是令人困惑和有问题的。无符号类型应该在很多方面被认为是他们自己的世界。 – supercat 2013-02-03 17:45:16

45

许多原因:

  • UINT不符合CLS,从而使内置型(阵列)依赖于它本来问题
  • 作为最初设计运行时禁止在堆上占用任何对象超过2GB的内存。由于最大大小的数组小于或等于此限制将是新的字节[int.MaxValue],因此人们可能会产生积极但非法的数组长度令人费解。
  • 从历史上看,C#从C和C++中继承了它的大部分语法和约定。在那些数组中只是指针算术,所以负数组索引是可能的(尽管通常是非法和危险的)。由于许多现有的代码假定数组索引被签名,所以这将是一个因素
  • 在相关说明中,在C/C++中对数组索引使用带符号整数意味着与这些语言和非托管函数进行互操作需要使用无论如何都会在这些情况下进行整合,这可能会由于不一致而混淆。
  • BinarySearch实现(许多算法中非常有用的组件)依赖于能够使用int的负范围来指示未找到该值这样一个值应该插入以保持的位置排序。
  • 在数组上操作时,您可能希望获取现有索引的负偏移量。如果您使用的偏移量会使您通过使用单位的数组的开始,那么环绕行为会使您的索引可能合法(因为它是正数)。如果使用int,结果将是非法的(但安全,因为运行时会防止读取无效内存)
相关问题