2010-09-21 42 views
6

编写可以归结为以下代码后:抛出负数组大小的OverflowException背后的原理?

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

我很惊讶,它抛出一个OverflowException。为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.

我想知道为什么选择了OverflowException。如果你问我,这很容易让人误解。这花费了我至少5分钟的调查时间(不包括我在这里的沉思)。任何人都可以在这个(对我的想法)特殊的设计决定?

+0

似乎有理由抛出这个例外给我。 – cjk 2010-09-21 16:02:20

+0

它是如何溢出任何描述? – spender 2010-09-21 16:02:51

回答

8

这几乎肯定是一种优化。 .NET框架代码在检查参数方面非常虔诚,让程序员陷入了成功的坑坑中。但这不是免费的。成本相当微不足道,许多类方法需要比检查花费更多的机器周期。

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

1

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

警告:这是纯粹的猜测。

+0

.NET中的数组大小存储为Int32,而不是无符号数。我相信这是为了保持数组符合CLS。 – 2010-09-21 16:10:18

+0

我原本是按照这些思路思考的,但规范非常具体,它是负面大小导致此异常。 – spender 2010-09-21 16:11:27

5

OverflowException,在文档中,基本上是一个溢流定义为东西:

产生的结果是数据类型

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

我可以看到ArgumentOutOfRangeException在某些方面可能更好 - 但是,数组定义中没有参数(因为它不是一种方法),所以它也不是一个完美的选择。