【问题标题】:Why is Count not an unsigned integer? [duplicate]为什么 Count 不是无符号整数? [复制]
【发布时间】:2011-04-09 04:24:24
【问题描述】:

可能的重复:
Why does .NET use int instead of uint in certain classes?
Why is Array.Length an int, and not an uint

我一直想知道为什么.Count 不是无符号整数而不是有符号整数?

以ListView.SelectedItems.Count 为例。元素个数不能小于0,为什么是signed int呢?

如果我尝试测试是否有选择的元素,我想测试

 if (ListView.SelectedItems.Count == 0) {}

但是因为是有符号整数,所以我要测试一下

 if (ListView.SelectedItems.Count <= 0) {}

或者有没有.Count可能是

【问题讨论】:

  • 我想这是为了方便,因为你不能将 uint 转换为 int 并且大多数人习惯于将 int 用于索引器......
  • 你仍然可以测试== 0,对吧?因为,正如您所指出的,它永远不会小于 0。毕竟,在某些时候,您的代码将做出一些基本假设,即其他人的代码将以成员名称所暗示的方式运行。我想说这使您能够假设Count 永远不会小于0,并检查是否相等。

标签: c# .net


【解决方案1】:

无符号整数不符合 CLS (Common Language Specification)

有关符合 CLS 的代码的更多信息,请参阅此链接:

http://msdn.microsoft.com/en-us/library/bhc3fa7f.aspx

【讨论】:

  • 虽然这回答了问题,但并没有解释。也许问题应该是,“为什么它不符合 CLS?”这确实是一个奇怪的决定。
  • 为什么 uint 不符合 CLS 的问题是一个单独问题的主题,这里已经提出了这个问题:stackoverflow.com/questions/6325/…
【解决方案2】:

Mabye,因为 uint 数据类型不是 CLS(通用语言规范)的一部分,因为并非所有 .Net 语言都支持它。

这是关于数组的非常相似的线程:

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

【讨论】:

    【解决方案3】:

    让我们从实际的角度来看。

    无论好坏,签名的 ints 是 .NET 中使用的 正常 类型的 ints。在 C 和 C++ 中使用签名的ints 也是正常的。因此,除非有充分的理由,否则大多数变量都被声明为 int 而不是无符号 int。

    在未签名的 int 和已签名的 int 之间进行转换存在问题并且并不总是安全的。

    在 32 位系统上,集合中不可能有接近 2^^32 个项目,所以签名的int 在所有情况下都足够大。 p>

    在 64 位系统上,无符号 int 不会给您带来太多好处,在大多数情况下,有符号 int 仍然足够大,否则您需要使用 64 位 int。 (我希望没有一个标准集合能够很好地处理 64 系统上接近 2^^31 个项目的任何地方!)

    因此,鉴于使用未签名的int 没有明显优势,为什么要使用未签名的int?

    【讨论】:

    • 我看到了一个明显的优势:当有人犯错时,例如(Names.Count &lt; 0)(而不是(Names.Count &gt; 0))编译器可以发出警告。我认为警告用户犯错是编译器的一项非常重要的任务,任何能够更容易检测错误的语言都比竞争对手有优势。事实上,这就是为什么我更喜欢编译语言。
    • 这个解释站不住脚。列表/字典/等中的项目数不能为负数,因此将 Count 设为 int 是愚蠢的。
    【解决方案4】:
    1. 它不符合 CLS,主要是为了更广泛地支持不同语言。

    2. 有符号的 int 可以轻松地从使用指针算法的 C 或 C++ 移植代码。

    3. Count 可以是表达式的一部分,其中总值可以为负数。特别是,计数与索引有直接关系,其中有效索引始终在 [0, Count - 1] 范围内,但使用负数结果,例如通过一些二分查找方法(包括 BCL 提供的方法)来反映应该插入新项目以保持顺序的位置。

    【讨论】:

      【解决方案5】:

      在 vb.net 中,正常的循环结构(“For/Next 循环”)将执行循环,其值达到并包括指定的最大值,这与 C 不同,C 可以轻松地循环低于上限的值。因此,通常需要指定一个循环,例如"对于 I=0 到 Array.Length-1";如果 Array.Length 为无符号且为零,则可能会导致明显的问题。即使在 C 语言中,也可以说“for (i=Array.Length-1; i GE 0; --i)”。有时我认为拥有一个 31 位整数类型会很有用,它支持对有符号和无符号 int 的扩展转换,但我从未听说过支持这种类型的语言。

      【讨论】:

      • 完全正确!! VB 不同:在 VB 中,真为 0,假为-1。根据这个公理,-1 是一个 int,不能用 unsigned int 来表示。这显然是一个 CPU 优化问题
      • 完全正确!! VB 不同:在 VB 中,真为 0,假为-1。根据这个公理,-1 是一个 int,不能用 unsigned int 来表示。我认为使用整数的有符号版本而不是无符号整数的原因显然是一个 CPU 优化问题:零的数字具有负值 -1。例如,逻辑方案中的 NOT 门对于如何判断值等于 0 或为空是有效的。
      • @user1587368: (two's-complement) signed int 的一个优点是,无论大小如何,此类类型都有 -1 作为“所有位集”值,而无符号类型的每个大小都有一个不同的“所有位设置”值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-16
      • 2018-04-30
      • 1970-01-01
      • 2016-02-17
      • 2022-01-20
      • 1970-01-01
      相关资源
      最近更新 更多