.net 作为索引的无符号数与有符号数

.net 作为索引的无符号数与有符号数,.net,unsigned,signed,indexing,.net,Unsigned,Signed,Indexing,在.Net中使用有符号数字作为索引的理由是什么 在Python中,可以通过发送负数从数组末尾开始索引,但在.Net中并非如此。 对于.Net来说,以后添加这样一个功能并不容易,因为它可能会破坏其他代码,可能会使用索引上的特殊规则(是的,这是一个坏主意,但我想它会发生) 并不是说我曾经需要索引大小超过2147483647的数组,但我真的无法理解它们为什么选择有符号的数字 这可能是因为在代码中使用有符号的数字更正常吗 编辑:我刚找到以下链接: Edit2:好的,Matthew Flaschen发

在.Net中使用有符号数字作为索引的理由是什么

在Python中,可以通过发送负数从数组末尾开始索引,但在.Net中并非如此。 对于.Net来说,以后添加这样一个功能并不容易,因为它可能会破坏其他代码,可能会使用索引上的特殊规则(是的,这是一个坏主意,但我想它会发生)

并不是说我曾经需要索引大小超过2147483647的数组,但我真的无法理解它们为什么选择有符号的数字

这可能是因为在代码中使用有符号的数字更正常吗

编辑:我刚找到以下链接:

Edit2:好的,Matthew Flaschen发布的帖子中还有几个很好的理由:

  • 历史原因,因为它是一种c语言
  • 与c的互操作

Unsigned不符合CLS。

使用0以下的值作为无效索引可能是一个长期的传统。如果找不到元素,像String.IndexOf这样的方法将返回-1。因此,必须对返回值进行签名。如果索引使用者需要无符号值,则必须a)检查并b)强制转换该值才能使用它。对于有符号索引,您只需要检查。

当然,为了简单起见。您喜欢对无符号整数进行大小运算吗?

无符号数的主要用途是从较小的整数合成较大的数,反之亦然。例如,如果一个人从一个连接接收到四个无符号字节,并希望将它们的值作为一个整体视为32位整数,那么使用无符号类型意味着可以简单地说:

value = byte0 | (byte1*256) | (byte2*65536) | (byte3*16777216); 值=字节0 |(字节1*256)|(字节2*65536)|(字节3*16777216); 相反,如果字节是有符号的,那么像上面这样的表达式会更复杂


我不确定我是否真的认为现在设计的语言没有任何理由不包括比最长有符号整数类型短的所有类型的无符号版本,其语义是所有整数(表示离散数量数字,而不是任何特定类型)默认情况下,完全适合最大签名类型的操作将像在该类型上操作一样执行。包含最大有符号类型的无符号版本将使语言规范复杂化(因为必须指定哪些操作必须适合于有符号类型的范围,哪些操作必须适合于无符号类型的范围),但如果不这样做,则设计语言时应该没有问题,以便(unsigned1-unsigned2>unsigned3)将产生“数字正确”的结果,即使
unsigned2
大于
unsigned1
[如果想要unsigned wrapparound,可以显式指定
if((Uint32)(unsigned1-unsigned2)>unsigned3)
].一种指定这种行为的语言肯定会大大改善C语言中存在的混乱局面(考虑到它的历史,这是合理的),C#或vb.net。

但微软的CLS规范是正确的?在这种情况下,他们有最终决定权,他们确实选择了使用有符号的数字。@Blindy:我认为他们想让CLS规范尽可能包含所有语言,并且不是所有语言都支持无符号数字(例如VB6,即使VB6不是CLS语言,我想他们可能希望增加互操作性的机会).@Blindy:Java甚至没有unsigned。请参阅。的可能重复似乎是合理的,但这是我能想到的唯一示例。使用负数作为索引是一个运行时错误。IndexOf可以用另一种方式实现。另一个示例是返回的位置如果找到项,则排序列表中项的从零开始的索引;否则,为负数,它是大于项的下一个元素索引的位补码,或者,如果没有较大的元素,则为计数的位补码。“您发布的示例代表了一个不良编程实践的完美示例。如果某人是这样一个业余程序员,即使是带符号的整数也不能将他从缓冲区溢出/溢出中解救出来。