【问题标题】:Why does .NET use int instead of uint in certain classes?为什么 .NET 在某些类中使用 int 而不是 uint?
【发布时间】:2010-10-21 10:10:16
【问题描述】:

我总是遇到使用int 来表示.Count 等内容的代码,即使在框架类中也是如此,而不是uint

这是什么原因?

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    UInt32 不是CLS compliant,因此它可能不适用于所有针对公共语言规范的语言。 Int32 符合 CLS,因此保证存在于所有语言中。

    【讨论】:

    • 但是为什么这会影响一个人是否使用 Int32 以特定语言进行编码?如果语言 X 不接受它,但语言 Y 接受,那么如果我在 Y 中编程,我为什么要关心 X?只是为了展示用多种语言实现的示例来展示功能,还是有其他原因我应该在 Y 中编程而在 X 中受到限制?
    • 通用语言规范的理念是您可以为所有语言提供一个基类库。如果 BCL 仅使用符合 CLS 的功能并且所有语言都支持所有符合 CLS 的功能,则可以从所有语言使用 BCL。如果您希望类库可以在编写时使用的其他语言中使用,这同样适用于您的类库。
    • @Adam:没有什么说您的代码必须仅符合 BCL 提供的内容。但是,BCL 旨在供任何符合 CLS 的组件使用,因此 BCL 必须将自身限制为 CLS 功能。
    【解决方案2】:

    int,在 c 中,被特别定义为处理器的默认整数类型,因此被认为是一般数值运算中最快的。

    【讨论】:

    • 感谢 Adam,我实际上需要额外的 uint 范围,但您认为使用它会降低我的应用程序的性能吗?
    • 在现代处理器中,无符号整数和有符号整数应该大致相同。如果存在差异,那是微不足道的,如果您需要每一盎司的性能,那么值得为您的特定编译器/操作系统/CPU/等进行基准测试。
    • 不,它不会改变程序的性能。要获得这样的答案,微基准是您的朋友(我推荐 MeasureIt)。 在我的计算机上 添加 uint 的执行速度似乎比 int 快 20%(尽管这么小的测量值不太可靠)。一般来说,担心这一点会被认为是过早优化;使用最适合情况的任何方法,如果它会导致可衡量的性能影响,请稍后对其进行优化。
    • @AdamDavis: 可以保持任意两个具有相同符号的任意Int32 值之间的算术差异的最小类型是Int32。要保持两个任意UInt32 值之间的差异[自然会有相同的“符号”],需要Int64。恕我直言,.NET 可能受益于 UInt31 类型,该类型可以隐式转换为 Int32
    • 这不是关于 C 的,而是关于 C#。
    【解决方案3】:

    只有当一个有符号和无符号值的和或乘积是一个大到足以容纳任一操作数的有符号类型,并且如果两个无符号值之间的差是一个大到足以容纳任何一个有符号值时,无符号类型才表现得像整数结果。因此,大量使用UInt32 的代码将经常需要将值计算为Int64。当操作数过大时,对有符号整数类型的操作可能无法像整数一样操作,但当操作数小时它们会表现得很好。即使操作数很小,对无符号类型的未提升参数的操作也会产生问题。例如,给定UInt32 x;,如果结果类型为x==0,则不等式x-1 < x 将失败,如果结果类型为Int32,则不等式x<=0 || x-1>=0 对于较大的x 值将失败。只有在 Int64 类型上执行操作时,才能支持这两种不等式。

    虽然有时以不同于整数算术的方式定义无符号类型的行为很有用,但表示计数之类的值通常应该使用行为类似于整数的类型——无符号类型通常不这样做除非它们小于基本整数类型。

    【讨论】:

      【解决方案4】:

      如果该数字本质上确实是无符号的,那么我将其声明为无符号整数。但是,如果我只是碰巧使用了正数范围内的数字(暂时),那么我将其称为 int。

      主要原因是:

      • 它避免了必须进行大量类型转换,因为大多数方法/函数都被编写为采用 int 而不是 unsigned int。
      • 它消除了可能的截断警告。
      • 您总是希望可以为您最初认为始终为正的数字分配一个负值。

      只是想到的一些快速想法。

      我曾经尝试非常小心并选择正确的未签名/签名,但我终于意识到它并没有真正带来积极的好处。它只会创造额外的工作。那么,为什么要通过混合和匹配来使事情变得困难。

      【讨论】:

      • 因此,例如,数据的长度在任何情况下都应该始终为正,但 NetworkStream.Read 返回一个 int?
      【解决方案5】:

      UInt32 不符合 CLS。 http://msdn.microsoft.com/en-us/library/system.uint32.aspx

      我认为多年来人们得出的结论是,使用无符号类型并没有真正提供那么多好处。更好的问题是通过将 Count 设置为 UInt32 可以获得什么?

      【讨论】:

      • 如果有的话,我会让 Count 成为 UInt16 - 它需要一半的空间,但您仍然可以拥有与 Int32 一样大的列表...
      • UInt16 不等于 Int32。因为 Int32 的正整数来自 Int31 的范围(而不是来自 Int16)。
      【解决方案6】:

      使用int的另一个原因:

      假设你有一个像这样的for-loop:

      for (i = someList.Count - 1; i >= 0; i--) {
        // Stuff
      }
      

      很明显,如果someList.Count 为零而unsigned,你就会遇到问题。

      【讨论】:

      • 谢谢,但是为什么要减去 1 呢?
      • 因为 someList 的索引是从零开始的。我宁愿使用 (i
      • 我明白了,但我个人从未见过有人在 for 循环中使用
      • 我也没有。嗯,我们这样看: for (i = list.Count - 1; i >= 0; i--) 表示从列表末尾开始。并不少见。
      • @rw-nandemo 这在哪里依赖有符号整数溢出? 0 - 1 不会在有符号整数类型上溢出,结果也很明确。
      【解决方案7】:

      有些东西使用 int 以便它们可以返回 -1,就好像它是“null”或类似的东西。如果 ComboBox 没有选择任何项目,它将为其 SelectedIndex 返回 -1。

      【讨论】:

      • 这些都很好,但是 .Count 对负值没有意义。
      • 顺便说一句,这些都不好,真的) SelectedIndex 返回 -1 的原因是第一个 .NET 版本没有可为空的值。如果没有找到或选择某些内容,强烈建议返回 null。
      【解决方案8】:

      一些旧库甚至InStr 使用负数来表示特殊情况。我相信要么是懒惰,要么是有负面的特殊价值。

      【讨论】:

        猜你喜欢
        • 2010-09-05
        • 1970-01-01
        • 2012-04-20
        • 2010-10-10
        • 1970-01-01
        相关资源
        最近更新 更多