1. ホーム
  2. c#

NullReferenceExceptionには、なぜNullであるという情報が含まれていないのでしょうか?

2023-11-20 03:19:24

質問

NullReferenceException がベースクラスのデータ (スタックトレースなど) 以外の実行時特有の情報を含まないのは、どのような設計上の判断によるものですか? また、式のどの部分が NULL だったかをすぐに教えてくれる Visual Studio 用の拡張機能はありますか?

どのように解決するのですか?

NRE は非常に低レベルの例外です。 64K 未満のアドレスからデータを読み込むように要求されたときに、プロセッサによって生成されるハードウェア例外 (「トラップ」) であります。 仮想メモリ空間のその領域は、特にポインタのバグを捕捉するために常にアンマップされています。 AccessViolationとして始まり、アドレスが0x00010000より小さいときにCLRによってNREになります。 その時点では、例外のコンテキストはほとんどなく、わかっているのはトラップを引き起こしたマシン コード命令のアドレスだけです。

そのマシン コード命令のアドレスを、プログラム内の名前付き変数に戻すリバース エンジニアリングは不可能です。 そのように動作することが重要であり、ジッターは生成された 非常に

そうでない場合は、非常に非効率的なコードを生成する必要があります。 合理的にできることは、ソース コードの行番号を回復することだけです。 それには、行番号情報を含むデバッグ情報(.pdb)が必要です。 CLR は .pdb ファイルを読み取る方法を知っており、それを使って例外のスタックトレースを生成します。 しかし、JITオプティマイザが行う最適化により、これはまだ不正確なことが多く、コードを動かしてしまう。 Debugビルドの場合のみ、一致が保証されます。 ReleaseビルドのPDBにソース行番号情報が含まれないのは、そのためです。 これを変更することができます。

この問題は非常にシンプルな解決策を持っています。 ランタイムに実行させる前に、自分自身で null をチェックし、自分自身の例外を生成します。 このテストは非常に安価で、まあナノ秒より短いです。