使用 uint 或 int

发布于 2024-12-06 08:35:40 字数 804 浏览 5 评论 0原文

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

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

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

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

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

参数tokenspositions中的所有元素不能为负数。如果结果是否定的,那么最后的结果就没有意义。因此,如果我对令牌和位置都使用 int,我必须在每次调用此函数时检查这些值(并返回无意义的值)值或如果发现负值则抛出异常???),这很乏味。

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

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

那么,总而言之,我该怎么办?

我可以提供两种情况:

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

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

Peter

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

Definitely, I know the basic differences between unsigned integers (uint) and signed integers (int).

I noticed that in .NET public classes, a property called Length is always using signed integers.

Maybe this is because unsigned integers are not CLS compliant.

However, for example, in my static function:

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

The parameter tokens and all elements in positions cannot be negative. If it's negative, the final result is useless. So if I use int both for tokens and positions, I have to check the values every time this function is called (and return non-sense values or throw exceptions if negative values found???), which is tedious.

OK, then we should use uint for both parameters. This really makes sense to me.

I found, however, as in a lot of public APIs, they are almost always using int. Does that mean inside their implementation, they always check the negativeness of each value (if it is supposed to be non-negative)?

So, in a word, what should I do?

I could provide two cases:

  1. This function will only be called by myself in my own solution;
  2. This function will be used as a library by others in other team.

Should we use different schemes for these two cases?

Peter

P.S.: I did do a lot of research, and there is still no reason to convince me not to use uint :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

沙与沫 2024-12-13 08:35:40

我看到三个选项。

使用uint。该框架不这样做,因为它不符合 CLS。但您必须符合 CLS 要求吗? (也有一些不有趣的算术问题突然出现;到处投射并不有趣。出于这个原因,我倾向于 void 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,那么它是有效的。

您有理由要求您的领域具有非消极性。它正在对一些概念进行建模。不妨将该概念提升为领域模型中的真正对象,并封装它附带的所有概念。

I see three options.

Use uint. The framework doesn't because it's not CLS compliant. But do you have to be CLS compliant? (There are also some not-fun issues with arithmetic that crop up; it's not fun to cast all over the place. I tend to void uint for this reason).

Use int but use contracts:

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

Make it explicit it exactly what you require.

Create a custom type that encapsulates the requirement:

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

Then:

public static double GetDistributionDispersion(Foo tokens, Foo[] positions) { }

Ah, nice. We don't have to worry about it in our method. If we're getting a Foo, it's valid.

You have a reason for requiring non-negativity in your domain. It's modeling some concept. Might as well promote that concept to a bonafide object in your domain model and encapsulate all the concepts that come with it.

歌枕肩 2024-12-13 08:35:40

我使用uint

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

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

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

我不介意 CLS 合规性,那为什么我应该介意呢?从我的角度来看,问题应该颠倒过来:当值不能为负时,为什么要使用整数?

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

I use uint.

Yes, other answers are all correct... But I prefer then uint for one reason:

Make interface more clear. If a parameter (or a returned value) is unsigned, it is because it cannot be negative (has you seen a negative collection count?). Otherwise, I need to check parameters, document parameters (and returned value) that cannot be negative; then I need to write additional unit tests for checking parameters and returned values (wow, and someone would complain for doing casts? Are int casts so frequent? No, by my experience).

Additionally, users are required to test returned values negativity, which may be worse.

I don't mind about CLS compliace, so why I should be? From my point of view, the question should be reversed: why should I use ints when value cannot be negative?

For the point of returning negative value for additional information (errors, for example...): I don't like so C-ish design. I think there may be a more modern design to accomplish this (i.e. use of Exceptions, or alterntively use of out values and boolean returned values).

唔猫 2024-12-13 08:35:40

是的,选择 int。我曾经尝试去 uint 自己,只是当我的库中有一些烦人的强制转换时,我才再次重构所有内容。
我猜想选择 int 的决定是出于历史原因,其中 -1 的结果通常表示某种错误(例如在 IndexOf 中)。

Yes go for int. I once tried to go uint myself only to refactor everything again as soon as I had my share of annoying casts in my lib.
I guess the decision to go for int is for historical reasons where often a result of -1 indicates some sort of error (for example in IndexOf).

你的往事 2024-12-13 08:35:40

国际。当您需要在不久的将来更改 API 时,它可以提供更大的灵活性。
例如Python经常使用负索引来表示从字符串末尾开始反向计数。

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

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

int. it gives more flexibility when you need to do a API change in the near future.
such as negative indexes are often used by python to indicate reversed counting from the end of string.

values also turns negative when overflows, assertion will catch it.

its a trade off for speed vs robustness.

命硬 2024-12-13 08:35:40

正如您所读到的,它违反了公共语言规范规则,但是该函数的使用频率如何,并且如果它将与其他方法组合在一起,那么它们通常会期望 int 作为参数,这将让你陷入塑造价值观的麻烦。

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

有趣的阅读 - SO链接

As you read it violates the Common Language Specification rules, but then how often will the function be used and in case it going to be clubbed up with other method its normal for them to expect int as parameter which would get you into the trouble of casting the values.

If you are going to make it available as a library then its better sticking to the conventional int else you need to implicitly take care of conditions wherein you might not get a positive value which would mean littering the checks across the pages.

Interesting Read - SO link

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文