この.NETの未処理の例外メッセージについて:
オブジェクト参照がオブジェクトインスタンスに設定されていません。
.NETがどのオブジェクトであるかを表示しないのはなぜですか nullかをですか?
nullエラーを確認して解決できることはわかっています。しかし、なぜ.NETは、どのオブジェクトがnull参照を持ち、どの式がトリガーされたNullReferenceExceptionかを指摘できないのですか?
この.NETの未処理の例外メッセージについて:
オブジェクト参照がオブジェクトインスタンスに設定されていません。
.NETがどのオブジェクトであるかを表示しないのはなぜですか nullかをですか?
nullエラーを確認して解決できることはわかっています。しかし、なぜ.NETは、どのオブジェクトがnull参照を持ち、どの式がトリガーされたNullReferenceExceptionかを指摘できないのですか?
回答:
(Visual Studio 2017の新しい例外ヘルパーについては、この回答の最後を参照してください)
このコードを考えてみましょう:
String s = null;
Console.WriteLine(s.Length);
これはNullReferenceException、2行目にをスローし、.NETがそれがsがスローされ、例外がスローされたときにnullことが。
なぜそのような情報が得られないのかを理解するには、実行するのはC#ソースではなくILであることを覚えておく必要があります。
IL_0001:ldnull IL_0002:stloc.0 // s IL_0003:ldloc.0 // s IL_0004:callvirt System.String.get_Length IL_0009:System.Console.WriteLineを呼び出します
callvirtをスローするのはオペコードでありNullReferenceException、評価スタックの最初の引数がnull参照(を使用してロードされたものldloc.0)である場合にそれを行います。
.NETがsそれがnull参照であったことを認識できる必要がある場合は、評価スタックの最初の引数がフォームから発生したことを何らかの方法で追跡する必要がありますs。この場合、それsがnullであることが簡単にわかりますが、値が別の関数呼び出しからの戻り値であり、変数に格納されていない場合はどうなりますか?とにかく、この種の情報は、.NET仮想マシンのような仮想マシンで追跡したいものではありません。
この問題を回避するには、すべてのパブリックメソッド呼び出しで引数のnullチェックを実行することをお勧めします(もちろん、null参照を許可しない限り)。
public void Foo(String s) {
if (s == null)
throw new ArgumentNullException("s");
Console.WriteLine(s.Length);
}
nullがメソッドに渡されると、問題が何であるかを正確に説明する例外(つまりsnull)が発生します。
4年後のVisual Studio 2017には、a NullReferenceExceptionがスローされたときにnullが何であるかを通知する新しい例外ヘルパーが追加されました。nullであるメソッドの戻り値である場合は、必要な情報を提供することもできます。
これはDEBUGビルドでのみ機能することに注意してください。
nullます。
nullOPはリリースビルドについてもデバッグビルドで十分であると彼/彼女が知りたいと主張していないことに注意してください。
null)を、そのオブジェクト参照を返したソースファイルの行と列に関連付ける際に問題が発生することはあまりありません。
次の場合のエラーメッセージをどのように表示しますか?
AnyObject.GetANullObject().ToString();
private object GetANullObject()
{
return null;
}
ここに報告する変数名はありません!
Object reference obtained from AnyObject.GetANullObject() not set to an instance of an object.エラーメッセージとして何かを期待します。
ええと、それはMicrosoftのエンジニアの答えです。ただし、デバッガを使用してウォッチを追加し、問題のあるものを見つけることはできます。
ただし、例外はNullReferenceException、参照が存在しないことを意味します。まだ作成されていないオブジェクトは取得できません。
but why .NET don't tell us which object is null?
これは、どのオブジェクトがnullであるかを認識していないためです。オブジェクトは単に存在しません!
私が言う場合も同じです。C#は.NET ILコードにコンパイルされます。.NET ILコードは名前または式を認識しません。参照とその場所のみを認識します。ここでも、存在しないものを手に入れることはできません。式または変数名が存在しません。
哲学:そもそも卵がないとオムレツは作れません。