0

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 のインスタンス化を「忘れる」と思います。

4

1 に答える 1

0

それはデバッガの問題のようです。ただし、生成されたコードは、作成したコードとはまったく異なることに注意してください。ラムダ式で myString を使用しているため、コンパイラは myString への参照を格納する隠しクラスを作成しました。命令ポインターをドラッグしているときに、このクラスの必要な初期化がソースで表されないため、スキップされる可能性があります。

アイデアとして、「if」の後の左ブラケットに命令ポインタをドラッグしてみてください。

于 2013-03-19T11:39:22.347 に答える