10

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

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

也许这是因为无符号整数不符合 CLS。

但是,例如,在我的静态函数中:

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

参数tokens和其中的所有元素positions不能为负数。如果它是否定的,最后的结果是没有用的。因此,如果我int同时使用 fortokenspositions,则每次调用此函数时都必须检查值(如果发现负值,则返回无意义的值或抛出异常???),这很乏味。

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

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

所以,一句话,我该怎么办?

我可以提供两种情况:

  1. 这个函数只会在我自己的解决方案中被我自己调用;
  2. 此函数将被其他团队中的其他人用作库。

我们应该对这两种情况使用不同的方案吗?

彼得

PS:我确实做了很多研究,仍然没有理由说服我不要使用uint:-)

4

5 回答 5

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) { }

很好。在我们的方法中,我们不必担心它。如果我们得到 a Foo,它是有效的。

您有理由要求在您的域中保持非消极性。它正在建模一些概念。不妨将该概念提升为域模型中的真正对象,并封装随之而来的所有概念。

于 2011-09-26T05:59:14.313 回答
3

我使用uint

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

使界面更清晰。如果一个参数(或返回值)是无符号的,那是因为它不能为负数(你见过负数收集计数吗?)。否则,我需要检查不能为负数的参数、文档参数(和返回值);那么我需要编写额外的单元测试来检查参数和返回值(哇,有人会抱怨进行强制转换吗?int 强制转换这么频繁吗?不,根据我的经验)。

此外,用户需要测试返回值的负性,这可能会更糟。

我不介意遵守 CLS,那我为什么要这么做呢?从我的角度来看,问题应该反过来:当值不能为负时,为什么要使用整数?

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

于 2011-09-26T13:58:52.377 回答
2

是的去int。我曾经尝试过自己去重构所有东西,只要我在我的库中有我那份烦人的演员表。我猜选择 int 的决定是出于历史原因,通常 -1 的结果表示某种错误(例如在 IndexOf 中)。

于 2011-09-26T05:58:53.830 回答
1

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

溢出时值也会变为负数,断言会捕获它。

它是速度与稳健性的权衡。

于 2011-09-26T05:52:45.673 回答
1

当您阅读它时,它违反了公共语言规范规则,但是该函数的使用频率如何,并且如果它将与其他方法混为一谈,它们通常会期望int作为参数,这会给您带来麻烦价值观。

如果您打算将其作为库提供,那么它最好坚持传统的 int ,否则您需要隐式处理可能无法获得正值的情况,这意味着在页面上乱扔支票。

有趣的阅​​读 - SO链接

于 2011-09-26T06:02:46.647 回答