使用uint或int

时间:2011-09-26 05:46:02

标签: c# int uint

当然,我知道无符号整数(uint)和有符号整数(int)之间的基本区别。

我注意到在.NET公共类中,名为Length的属性总是使用有符号整数。

可能这是因为无符号整数不符合CLS。

然而,例如,在我的静态函数中:

public static double GetDistributionDispersion(int tokens, int[] positions)

参数tokenspositions中的所有元素都不能为负数。如果它是否定的,最终结果是无用的。因此,如果我inttokens同时使用positions,我必须在每次调用此函数时检查值(如果找到负值,则返回非感知值或抛出异常? ??),这很乏味。

好的,那么我们应该对这两个参数使用uint。这对我来说真的很有意义。

然而,我发现,与许多公共API一样,它们几乎总是使用int。这是否意味着在他们的实现中,他们总是检查每个值的负面(如果它应该是非负的)?

所以,总之,我该怎么办?

我可以提供两种情况:

  1. 此功能只能由我自己在我自己的解决方案中调用;
  2. 此功能将被其他团队中的其他人用作库。
  3. 我们应该为这两种情况使用不同的方案吗?

    彼得

    P.S。:我做了很多研究,仍然没有理由说服我不要使用uint: - )

5 个答案:

答案 0 :(得分:5)

我看到三个选项。

使用uint。该框架不是因为它不符合CLS。但你必须符合CLS吗? (还有一些非常有趣的算术问题突然出现;在整个地方进行投射并不好玩。出于这个原因,我倾向于使uint无效。)

使用int但使用合同:

Contract.Requires(tokens >= 0);
Contract.Requires(Contract.ForAll(positions, position => position >= 0));

明确说明你需要的内容。

创建一个封装需求的自定义类型:

struct Foo {
    public readonly int foo;

    public Foo(int foo) {
        Contract.Requires(foo >= 0);
        this.foo = foo;
    }

    public static implicit operator int(Foo foo) {
        return this.foo;
    }

    public static explicit operator Foo(int foo) {
        return new Foo(foo);
    }
}

然后:

public static double GetDistributionDispersion(Foo tokens, Foo[] positions) { }
啊,太好了。我们不必在我们的方法中担心它。如果我们收到Foo,则该信息有效。

您有理由要求您的域名中包含非负面消息。它正在建模一些概念。不妨将这个概念推广到域模型中的真实对象,并封装随附的所有概念。

答案 1 :(得分:3)

我使用 uint

是的,其他答案都是正确的...但我更喜欢 uint ,原因之一是:

让界面更加清除。如果参数(或返回值)是无符号的,那是因为它不能为负数(您是否看到了负集合计数?)。否则,我需要检查不能为负的参数,文档参数(和返回值);然后我需要编写额外的单元测试来检查参数和返回的值(哇,有人会抱怨做演员表演吗?int casts如此频繁?不,根据我的经验)。

此外,用户需要测试返回值否定性,这可能更糟。

我不介意CLS complia,所以为什么我应该?从我的观点来看,问题应该颠倒过来:当价值不能为负时,我为什么要使用整数?

对于附加信息(错误,例如......)返回负值的观点:我不喜欢 C-ish 设计。我认为可能有更现代的设计来实现这一点(即使用异常,或者交替使用out值和布尔返回值)。

答案 2 :(得分:2)

是的,去int。我曾经尝试过自己只是为了在我的lib中有一些讨厌的演员时再次重构一切。 我认为选择int的决定是出于历史原因,通常结果为-1表示存在某种错误(例如在IndexOf中)。

答案 3 :(得分:1)

int值。当您需要在不久的将来进行API更改时,它提供了更大的灵活性。 例如,python通常使用负索引来表示从字符串末尾反向计数。

当溢出时,

值也会变为负值,断言会捕获它。

它是速度与稳健性的折衷。

答案 4 :(得分:1)

正如您所读到的那样违反了公共语言规范规则,但随后会使用该函数的频率如何,并且如果它将使用其他方法进行处理,那么它们通常需要int作为参数让你陷入铸造价值的麻烦。

如果你打算把它作为一个库提供,那么它更好地坚持传统的int,你需要隐含地处理你可能没有获得正值的条件,这意味着在页面上乱扔乱码。< / p>

Interesting Read - SO link