使用负数组大小抛出OverflowException背后的基本原理?

编写完可以归结为以下内容的代码后:

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

我很惊讶它抛出了一个OverflowException 。 OverflowException状态的文档:

在已检查上下文中的算术,转换或转换操作导致溢出时引发的exception。

我无法看到为这个exception提供的描述如何提供负的大小和数组长度,所以深入研究并发现这确实是指定的行为:

尺寸长度的计算值validation如下。 如果一个或多个值小于零,则抛出System.OverflowException,并且不执行进一步的步骤。

我想知道为什么选择了OverflowException。 如果你问我,那就太误导了。 我花了至少5分钟的调查时间(不计算我的思考)。 任何人都可以(根据我的想法)对这个特殊的设计决定有所了解吗?

这几乎肯定是一种优化。 .NET框架代码非常适合检查参数,让程序员陷入成功之中。 但这不是免费的。 成本相当微小,许多类方法比检查花费的机器周期多得多。

但arrays很特别。 它们是框架中非常核心的数据结构。 几乎每个集合类都建立在它们之上。 Array类中的任何开销都会直接影响其上的大量代码的效率。 避免检查是可以的,当内部代码需要将值转换为unsigned时,它会被隐式检查。 它很少见。 因此,检查两次并不值得更好的exception消息。

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

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

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

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

可能是因为该大小是unsigned int。 它将-1存储为二进制补码,当它被视为无符号整数时,是可以存储的最大正整数。 如果此数字大于数组的可能大小,则会溢出。

警告:这是纯粹的猜测。