VS2010 で C# コードをデバッグしているときに、説明できない興味深い動作をテストします。以下の非常に単純化されたコードを使用します。
public void Go()
{
var test = new Random().Next(10) % 2 == 0; // Simulate various cases
var qry = new[] { "bla", "ble", "bli", }.ToList(); // Get whole list
//string myString; // If declare out of scope OK
if (test) // BreakPoint here and dragNDrop on next line
{
var myString = "bli"; // declare and instanciate in scope => NullReferenceException
qry = qry.Where( item => item == myString ).ToList(); // filter the list
}
}
マウスでテスト値をテストせずに if スコープに入ろうとすると、NullReferenceException がスローされて myString をインスタンス化できません。「機能的な」コードを取得するには、スコープ外で myString を宣言するだけです。なぜVSがifテストを踏み越えさせてくれないのか理解できません.誰かがこの奇妙な例外を説明してくれたら嬉しいです. ありがとう
編集: 2 つの IL コードを比較した後 (myString 宣言が行われる場所によって異なります)、VS は生成された非表示クラスでnewobj命令を「実行できず」 、文字列値の割り当てが null 値で行われることがわかります。「範囲外」宣言版ではメソッドの先頭からnewobj命令を作成します。
ILCode (範囲内):
IL_0041: brtrue.s IL_006e // if (test)
IL_0043: newobj instance void ConsoleApplication5.BreakPointTest/'<>c__DisplayClass1'::.ctor()
IL_0048: stloc.2
IL_0049: nop
IL_004a: ldloc.2
IL_004b: ldstr "bli"
IL_0050: stfld string ConsoleApplication5.BreakPointTest/'<>c__DisplayClass1'::myString
ポインターのジャンプは nop/ldloc.2 命令で終了し、c__DisplayClass1 のインスタンス化を「忘れる」と思います。