6

次のように要約できるコードを記述した後:

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

OverflowExceptionがスローされたことに驚きました。OverflowException状態のドキュメント:

チェックされたコンテキストでの算術、キャスト、または変換操作の結果、オーバーフローが発生した場合にスローされる例外。

負のサイズと配列の長さを指定すると、この例外の説明にどのように適合するかがわかりませんでした。少し深く掘り下げて、これが実際に指定された動作であることがわかりました。

寸法長の計算値は、次のように検証されます。1つ以上の値がゼロ未満の場合、System.OverflowExceptionがスローされ、それ以上のステップは実行されません。

なぜOverflowExceptionが選ばれたのだろうか。あなたが私に尋ねるなら、それはかなり誤解を招きます。それは私に少なくとも5分の調査を要しました(ここで私の考えを数えません)。誰かがこの(私の考えでは)独特の設計決定に光を当てることができますか?

4

3 に答える 3

8

これはほぼ間違いなく最適化です。.NET フレームワークのコードは、引数をチェックしてプログラマーを成功への落とし穴に陥らせることに関してかなり宗教的です。しかし、それは無料ではありません。コストはごくわずかです。多くのクラス メソッドは、チェックに費やされるよりもはるかに多くのマシン サイクルを必要とします。

しかし、配列は特別です。それらは、フレームワークの非常にコアなデータ構造です。ほとんどすべてのコレクション クラスは、それらの上に構築されます。Array クラスにかかるオーバーヘッドは、その上にある多くのコードの効率に直接影響します。内部コードが値を unsigned にキャストする必要がある場合は、とにかく暗黙的にチェックされます。そして、それがトリップすることは非常にまれです。したがって、それを 2 回チェックすることは、より優れた例外メッセージに値するものではありません。

于 2010-09-21T16:43:55.497 に答える
5

ドキュメントのOverflowExceptionは、基本的にオーバーフローを次のようなものとして定義しています。

データ型の範囲外の結果を生成する

この場合、負の値は配列サイズ (実際には任意のサイズ) の有効範囲外です。

ArgumentOutOfRangeExceptionがいくつかの点で優れている可能性があるという議論を見ることができましたが、配列定義には (メソッドではないため) 引数が含まれていないため、これも完璧な選択ではありません。

于 2010-09-21T16:09:44.263 に答える
1

そのサイズが unsigned int であることが原因である可能性があります。-1 を 2 の補数で格納します。これは、unsigned int として見た場合、格納できる最大の正の整数です。この数値が配列の可能なサイズより大きい場合、オーバーフローします。

警告: これは純粋な憶測です。

于 2010-09-21T16:06:14.050 に答える