负数组大小引发 OverflowException 背后的基本原理?
在编写可以归结为以下内容的代码后:
var size=-1;
var arr=new byte[size];
我很惊讶它抛出了 溢出异常。 OverflowException 的文档指出:
我看不出为 和 数组长度提供负大小如何适合此异常给出的描述,因此深入研究并发现这确实是指定的行为:
尺寸长度的计算值验证为接下来。如果一个或多个值小于零,则抛出 System.OverflowException 并且不执行进一步的步骤。
我想知道为什么选择 OverflowException。如果你问我的话,这是相当误导的。我花了至少 5 分钟的时间进行调查(不包括我在这里的思考)。谁能阐明这个(在我看来)独特的设计决策?
After writing code that can be boiled down to the following:
var size=-1;
var arr=new byte[size];
I was surprised that it threw an OverflowException. The docs for OverflowException state:
I couldn't see how providing a negative size for and array length fits into the description given for this exception, so delved a little deeper and found that this is indeed the specified behaviour:
I wonder why OverflowException was chosen. It's pretty misleading if you ask me. It cost me at least 5 minutes of investigation (not counting my musings here). Can anyone shed any light on this (to my thinking) peculiar design decision?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这几乎肯定是一种优化。 .NET 框架代码非常热衷于检查参数,以免程序员陷入成功的陷阱。但这并不是免费的。成本相当微小,许多类方法花费的机器周期比检查所花费的机器周期多得多。
但数组很特殊。它们是框架中非常核心的数据结构。几乎每个集合类都是建立在它们之上的。 Array 类中的任何开销都会直接影响位于其之上的大量代码的效率。避免检查是可以的,当内部代码需要将值转换为无符号时,无论如何都会隐式检查它。而且它很少发生跳闸。因此检查两次并不值得更好的异常消息。
This is almost certainly an optimization. The .NET framework code is pretty religious about checking arguments to let the programmer fall in the pit of success. But that doesn't come for free. The cost is fairly minuscule, many class methods take lots more machine cycles than is spent on the checking.
But arrays are special. They are the very core data structure in the framework. Almost every collection class is built on top of them. Any overhead put in the Array class directly impacts the efficiency of a lot of code that sits on top of it. Avoiding the check is okay, it gets implicitly checked anyway when the internal code needs to cast the value to unsigned. And it is very rare that it trips. So checking it twice is not quite worth the better exception message.
OverflowException,在文档中,基本上将溢出定义为以下内容: :
。在这种情况下,负值超出了数组大小(或者实际上是任何大小)的有效范围。
我可以看到 ArgumentOutOfRangeException 在某些方面可能是这样的论点,更好 - 但是,数组定义中不涉及任何参数(因为它不是方法),因此它也不是一个完美的选择。
OverflowException, in the documentation, basically defines an overflow as something that:
In this case, negative values are outside of the valid range for an array size (or really, any size).
I could see the argument that ArgumentOutOfRangeException might be, in some ways, better - however, there is no argument involved in an array definition (as its not a method), so it, too, would not be a perfect choice.
可能是因为该大小是无符号整数。它将 -1 以二进制补码形式存储,当将其视为无符号整数时,它是可以存储的最大正整数。如果这个数字大于数组的可能大小,它将溢出。
警告:这纯粹是猜测。
It might be because that size is an unsigned int. It stores -1 in two's complement, which when looked at as a unsigned int, is the maximum positive integer that can be stored. If this number is bigger than the possible size of an array, it will overflow.
Warning: this is pure speculation.