【问题标题】:Rationale behind OverflowException thrown with negative array size?以负数组大小抛出 OverflowException 背后的基本原理?
【发布时间】:2010-09-21 15:51:56
【问题描述】:

写完代码后可以归结为:

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

我很惊讶它抛出了OverflowExceptionOverflowException 状态的文档:

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.

我想知道为什么选择了 OverflowException。如果你问我,这很误导人。这花了我至少 5 分钟的调查时间(这里不算我的沉思)。任何人都可以解释这个(我认为)特殊的设计决定吗?

【问题讨论】:

  • 向我抛出这个异常似乎是合理的。
  • 任何描述都溢出了怎么办?

标签: c# arrays specifications overflowexception


【解决方案1】:

这几乎可以肯定是一种优化。 .NET 框架代码非常热衷于检查参数以让程序员陷入成功的陷阱。但这不是免费的。成本相当微不足道,许多类方法花费的机器周期比检查所花费的要多得多。

但是数组是特殊的。它们是框架中非常核心的数据结构。几乎每个集合类都建立在它们之上。 Array 类中的任何开销都会直接影响其上的许多代码的效率。避免检查是可以的,当内部代码需要将值强制转换为无符号时,它会被隐式检查。它跳闸的情况非常罕见。所以检查两次并不值得更好的异常消息。

【讨论】:

    【解决方案2】:

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

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

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

    我可以看到ArgumentOutOfRangeException 在某些方面可能更好的论点 - 但是,数组定义中不涉及任何论点(因为它不是方法),所以它也不会是完美的选择。

    【讨论】:

      【解决方案3】:

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

      警告:这纯属猜测。

      【讨论】:

      • 数组大小在 .NET 中存储为 Int32,而不是无符号数。我相信这样做是为了保持数组符合 CLS。
      • 我最初是按照这些思路考虑的,但规范非常明确,它是导致此异常的负大小。
      猜你喜欢
      • 2011-03-11
      • 2015-08-18
      • 1970-01-01
      • 1970-01-01
      • 2014-12-19
      • 1970-01-01
      • 2013-02-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多