代码之家  ›  专栏  ›  技术社区  ›  spender

基本原理在使用负数组大小引发溢出异常之后?

  •  6
  • spender  · 技术社区  · 14 年前

    在编写了可以归结为以下内容的代码之后:

    var size=-1;
    var arr=new byte[size];
    

    我很惊讶它扔了一个 OverflowException . 的文档 溢出异常 状态:

    The exception that is thrown when an arithmetic, casting, or conversion operation in a checked context results in an overflow.

    我看不出为这个异常提供一个负的大小和数组长度如何符合给定的描述,所以深入研究了一点,发现这确实是指定的行为:

    The computed values for the dimension lengths are validated as follows. If one or more of the values are less than zero, a System.OverflowException is thrown and no further steps are executed.

    我想知道为什么选择了溢出异常。如果你问我的话,那是很误导人的。我花了至少5分钟的时间进行调查(不包括我在这里的沉思)。有人能解释一下这个(我的想法)特殊的设计决策吗?

    3 回复  |  直到 11 年前
        1
  •  8
  •   Hans Passant    11 年前

    这几乎可以肯定是一种优化。NET框架代码非常重视检查参数,以让程序员陷入成功的深渊。但这不是免费的。成本相当低,许多类方法比检查花费的机器周期要多。

    但是数组是特殊的。它们是框架中最核心的数据结构。几乎每个集合类都建立在它们之上。数组类中的任何开销都会直接影响位于它上面的许多代码的效率。避免检查是可以的,当内部代码需要将值强制转换为无符号时,它仍然会被隐式检查。而且它很少旅行。因此,检查两次并不值得得到更好的异常消息。

        2
  •  5
  •   Reed Copsey    14 年前

    OverflowException 在文档中,基本上将溢出定义为:

    生成超出数据类型范围的结果

    在这种情况下,负值超出了数组大小(或任何大小)的有效范围。

    我可以看到这样的论点 ArgumentOutOfRangeException 在某些方面可能会更好——然而,数组定义中没有涉及参数(因为它不是一个方法),因此它也不是一个完美的选择。

        3
  •  1
  •   xxpor    14 年前

    这可能是因为该大小是一个无符号整数。它将-1存储在2的补码中,当将其视为无符号整数时,它是可以存储的最大正整数。如果这个数字大于数组的可能大小,它将溢出。

    警告:这纯粹是猜测。