【问题标题】:Why do functions take an int as an argument when its value logically can not be < 0为什么函数的值在逻辑上不能<0时将int作为参数
【发布时间】:2013-08-31 01:25:01
【问题描述】:

当我编写带有确定特定长度的参数的函数时,我总是使用uint。因为值是负数是没有意义的。

但我在 .Net 框架中看到了相反的情况(经常)。 例如:http://msdn.microsoft.com/en-us/library/xsa4321w.aspx

将 String 类的新实例初始化为指定的 Unicode 字符所指示的值,该字符重复指定的次数。

public String(
    char c,
    int count
)

它还指出,当 `count 小于零时,会抛出 ArgumentOutOfRangeException。”

那么为什么不将count 参数设为uint!?

【问题讨论】:

标签: .net arguments int uint


【解决方案1】:

我有a similar question ages ago,虽然更多用于我自己的接口,而不是核心接口。

简短的回答(由 Eric Lippert 给出,并在 answers to other questions 中重复)是:公共语言规范规则规定您不应在公共接口中使用 uint,因为并非所有设计的语言都可以工作.NET 实际上这样的类型。想到 J# 之类的 Java 衍生产品——Java 只有带符号的整数类型。

【讨论】:

  • 该线程有很好的信息。这个帖子也有一些相关信息:stackoverflow.com/questions/1555154/…
  • 是的,这当然也是要考虑的事情(并且作为对我的问题的回答),但考虑到 .NET 的历史,我认为这比限制类型更小系统到几乎可以使用所有语言的类型。那是在 90 年代末 / 2000 年代初,当时微软仍然认为 Java 是一种必要的支持语言。
  • 哇!我从未听说过/读过Common Language Specification rules。它完全不同于良好的编码实践。感觉合乎道德!
【解决方案2】:

C 中的无符号类型有两个主要用途:

  1. 在某些情况下,当计算超出某个类型的范围时,具有将“换行”的值很有用。例如,在计算多种哈希或校验和时,在忽略溢出的情况下简单地执行一堆加法或乘法比使用过大的变量和/或条件逻辑来防止溢出要方便得多。

  2. 有时让一个两字节变量能够容纳高达 65,535 而不仅仅是 32,767 的值很有用;有时将四字节变量增加到 4,294,967,295 很有用,但这种情况不太常见。

在 C 中,尝试将 -1 存储到 unsigned 变量中需要存储(没有任何类型的错误或尖叫)当添加到 +1 时将产生零的值。这对于第一个使用场景非常有用;第二个是不可取的,但是由于 C 从未对有符号整数进行任何类型的溢出捕获,因此它可以被认为是对 numbers 计算时会发生坏事的原则的扩展(而不是比代数环)超出范围。

与 C 不同,C# 支持数字溢出检测,因此可以将其应用于第二种使用方式,同时仍允许第一种使用方式。不幸的是,该确定是基于已检查或未检查的数字上下文,而不是基于变量、参数或值的类型。因此,如果一个方法要接受一个UInt32 类型的参数并且unchecked 上下文中的代码试图传入一个值-1,那么该方法将把它看作一个值4,294,967,295。无法将参数标记为“这应该是一个介于 0 和 4,294,967,295 之间的值;如果是其他值,请尖叫,无论检查/未检查状态如何。因此让代码接受更安全如果上限 2,147,483,647 足够,则为 Int32,否则为 Int64

【讨论】:

    猜你喜欢
    • 2019-02-27
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 2011-10-27
    • 2017-08-31
    • 1970-01-01
    相关资源
    最近更新 更多