2013-03-19 3 views
0

При отладке кода C# с 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 
     } 
    } 

Когда я пытаюсь войти в рамки, если без проверки тестового значения с помощью мыши, то туЗЬптд не может быть с созданием экземпляра NullReferenceException забросил. Чтобы получить «функциональный» код, мне просто нужно объявить myString из области действия. Я не понимаю, почему В.С. не может позволить мне пройти тест if, и я буду счастлив, если кто-нибудь сможет объяснить мне это странное исключение. Благодаря

EDIT: После сравнения два коды IL (в зависимости от того, где производятся декларация туЗЬптда) я могу видеть, что VS «не может» выполнить команду newobj на скрытом классе генерируемого и уступке Строковое значение выполняется с нулевым значением. В версии декларации «вне сферы действия» инструкция newobj производится с начала метода.

ILCode (InScope):

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 

Я думаю, что скачок финиша pointeur на инструкции NOP/ldloc.2, и "забыть" о создании экземпляра c__DisplayClass1.

+0

Вы строите в режиме выпуска случайно? Оптимизация компилятора в режиме выпуска может сделать что-то для кода, что делает процесс отладки немного несовместимым с тем, что вы видите в коде. – jlew

+0

Я пробовал этот код (под отладчиком), и он отлично работает в любом случае для меня. –

+0

И работает тоже с перемещением указателя инструкции? – user2186214

ответ

0

Это похоже на проблему отладчика. Но имейте в виду, что сгенерированный код совсем не похож на тот, который вы написали. Вы используете myString в выражении лямбда, и по этой причине компилятор создал скрытый класс, в котором хранится ссылка на myString. Когда вы перетаскиваете указатель на команду, необходимые инициализации этого класса могут быть пропущены, потому что они не представлены в вашем источнике.

Как идея, попробуйте перетащить указатель инструкции на открывающий кронштейн после «если».

+0

Спасибо за ответ. – user2186214

+0

Простите, это мой первый вопрос ... (введите ключ ...). Я строю в режиме отладки без оптимизации, и когда я перетаскиваю только открытую скобку: тот же результат. @Alex: вы должны иметь право с инициализацией скрытого класса, представляющего лямбда. Я буду искать в этом направлении, потому что я не знаю, как это сделать. – user2186214

Смежные вопросы