使用uint vs int

Elo*_*off 78 c#

我已经观察了一段时间C#程序员倾向于在任何地方使用int,并且很少使用uint.但我从来没有找到一个令人满意的答案为什么.

如果您的目标是互操作性,则uint不应出现在公共API中,因为并非所有CLI语言都支持无符号整数.但这并不能解释为什么int如此普遍,即使在内部课程中也是如此.我怀疑这是因为在BCL中谨慎使用uint的原因.

在C++中,如果你有一个负值没有意义的整数,你选择一个无符号整数.

这清楚地表明不允许或不期望负数,编译器会为您做一些检查.我还怀疑在数组索引的情况下,JIT可以轻松地删除下限检查.

但是,在混合int和单位类型时,需要额外的护理和演员表.

是否应该使用更多?为什么?

jjn*_*guy 74

int比类型更短uint.

  • 使用`int`来索引数组我感到很自在,因为我永远不会有负索引.似乎盲目地明白在这种情况下应该使用"uint". (27认同)
  • @Justin:一般来说,"魔术数字"如-1并不是一个好主意.切换到long意味着无缘无故地使用2x内存......如果您不需要与其他API交互,"unit"肯定是有价值的. (12认同)
  • @MarkH完全同意,但是当进行反向迭代时,它可以以下形式有用:`for(int i = arr.Length - 1; i> = 0; i--){}`.使用uint执行此操作将导致溢出异常或更糟糕的是,无限循环. (3认同)
  • 我怀疑这非常接近事实.为什么在99%的时间(根据我的经验)`int`使用`uint`就足够了? (2认同)
  • 更不用说,更具可读性。如果您曾经通过代码/算法让别人阅读的代码/算法可能没有您的经验丰富,那么使用很多`uint`可能会使它们挂起来。在需要控制范围的所有情况下,`int`是完全可以接受的。 (2认同)

Ree*_*sey 48

uint我怀疑你观察为什么没有在BCL中使用是主要原因.

UInt32不符合CLS,这意味着它完全不适合在公共API中使用.如果您要在私有API中使用uint,这将意味着转换到其他类型 - 并且通常更容易和更安全地保持类型相同.

我还怀疑这在C#开发中并不常见,即使C#是唯一使用的语言,主要是因为它在BCL中并不常见.一般来说,开发人员试图(谢天谢地)模仿他们构建的框架的样式 - 在C#的情况下,这意味着尝试使您的API(公共和内部)看起来尽可能像.NET Framework BCL.这意味着谨慎使用uint.


Dan*_*ker 18

通常int就足够了.如果您满足以下所有条件,您可以使用uint:

  • 它不适用于公共API(因为uint它不符合CLS).
  • 你不需要负数.
  • 您(可能)需要额外的范围.
  • 没有在比较中使用它< 0,因为它永远不会true.
  • 没有在比较中使用它>= 0,因为它永远不会false.

最后一个要求经常被遗忘,并会引入错误:

static void Main(string[] args)
{
    if (args.Length == 0) return;
    uint last = (uint)(args.Length - 1);

    // This will eventually throw an IndexOutOfRangeException:
    for (uint i = last; i >= 0; i--)
    {
        Console.WriteLine(args[i]);
    }
}
Run Code Online (Sandbox Code Playgroud)


lor*_*ova 12

1)坏习惯.认真.即使在C/C++中也是如此.

想想常见的for模式:

for( int i=0; i<3; i++ )
    foo(i);
Run Code Online (Sandbox Code Playgroud)

绝对没有理由在那里使用整数.你永远不会有负面价值.但是几乎每个人都会以这种方式做一个简单的循环,即使它包含(至少)另外两个"样式"错误.

2)int被认为是机器的原生类型.


JSB*_*ոգչ 5

我更喜欢uintint除非负数实际上在可接受的值范围内。特别是,接受一个int参数但ArgumentException如果数字小于零则抛出一个是愚蠢的——使用uint!

我同意它uint未被充分利用,我鼓励其他人更多地使用它。

  • @Henri:C# 没有从 int 到 uint 的隐式转换,因此没有“如果有人传递负值”。当然,对上限进行边界检查仍然是合适的(但现在您只需要检查一次而不是两次)。 (20认同)
  • 只接受 uint 而不检查边界是非常危险的。如果有人传递负值,CLR 会将其解释为一个大整数,这意味着对于 -1,您将获得 uint.maxvalue。这不是我们想要的行为。 (8认同)