Удивительный CLR / JIT? поведение - отложенная инициализация локальной переменной

Я только что столкнулся с чем-то довольно странным при запуске приложения в Debug режиме (VS 2008 Express, Any Cpu). Я был бы признателен, если бы кто-нибудь просветил меня относительно того, что здесь происходит?

// PredefinedSizeGroupMappings is null here
Dictionary<string, int> groupIDs = PredefinedSizeGroupMappings ?? new Dictionary<string, int>();

// so groupIDs is now initialized as an empty Dictionary<string, int>, as expected

// now: PredefinedSizesMappings is null here - therefore I expect sizeIds
// to be initialized as an empty dictionary:
Dictionary<string, string> sizeIds = PredefinedSizesMappings ?? new Dictionary<string, string>(); 

// but at this point sizeIds is still null! :O That's what debugger shows.
var groupsReport = new AutomappingReportArgs();

// only once we get here - it's suddenly not... The debugger shows: "Count = 0"
var sizesReport = new AutomappingReportArgs();

Класс AutomappingReportArgs не имеет никакого отношения к переменной sizeIds, хотя его конструктор размещает несколько словарей:

public AutomappingReportArgs()
{
    ChangedNames = new Dictionary<string, KeyValuePair<string, string>>();
    CreatedAfterRename = new Dictionary<string, string>();            
    Existing = new Dictionary<string, string>();
    Created = new Dictionary<string, string>();
    Failed = new Dictionary<string, string>();
}

Я предполагаю, что это должен быть какой-то компилятор или оптимизация CLR, но я хотел бы узнать механизм этого более подробно. В чем причина этой «отложенной инициализации»?

И почему это непоследовательно, почему сразу работает для Dictionary<string, int>, а не для Dictionary<string, string>? Это потому, что компилятор не видит впереди Dictionary<string, int> инициализацию и не может отложить ее на потом?


person Konrad Morawski    schedule 08.03.2012    source источник
comment
Вы очистили свою сборку и попытались снова?   -  person Oded    schedule 08.03.2012
comment
Я повторил это несколько раз. Почистите в каком смысле?   -  person Konrad Morawski    schedule 08.03.2012
comment
Очистите, как при щелчке правой кнопкой мыши по Решению, а затем по Очистить раствор.   -  person Oded    schedule 08.03.2012
comment
В VS 2008 Express такого нет   -  person Konrad Morawski    schedule 08.03.2012
comment
Тогда должна быть Rebuild.   -  person Oded    schedule 08.03.2012
comment
Я так и сделал, но продолжает вести себя так же.   -  person Konrad Morawski    schedule 08.03.2012
comment
На первый взгляд кажется, что ваш код и собранные сборки не синхронизированы. Попробуйте удалить папку bin.   -  person Oded    schedule 08.03.2012
comment
@Oded спасибо, что все равно изучили. Озадачивающий   -  person Konrad Morawski    schedule 08.03.2012
comment
Поместите в какую-нибудь строку, напечатав там значение sizeIdss. Не доверяйте отладчику.   -  person CodesInChaos    schedule 08.03.2012
comment
Ну, действительно, он распечатывает, что переменная не равна нулю. И отладчик тоже мгновенно просыпается от этого. Предварительно просматриваемое значение больше не равно нулю.   -  person Konrad Morawski    schedule 08.03.2012
comment
так что вы, вероятно, обнаружили проблему с экспресс-отладчиком VS2008, а не проблему с CLR :)   -  person Marek    schedule 08.03.2012
comment
Я вообще не думал об этом как о проблеме - поскольку он всегда инициализирует переменную до того, как она будет фактически использована в коде. Пытаясь представить, что происходит, я подозревал, что он, возможно, может заглянуть в будущее и увидеть хорошо, в любом случае есть куча пустых Dictionary<string, string>, которые выделяются в следующем кадре стека, так что давайте подождем с этим до тех пор и выполним все за один раз, тем самым как-то ускоряя процесс. (???)   -  person Konrad Morawski    schedule 08.03.2012


Ответы (1)


Это довольно стандартное поведение при отладке оптимизированного кода. Вряд ли здесь так. Скорее всего, это ошибка в отладчике. Было выпущено важное исправление SP1 для VS2008, которое устранило ряд проблем отладчика.

Вы найдете ссылку на исправление в этом ответе. Не уверен, насколько исправление применимо к Express Edition, все должно быть в порядке, но я не могу этого гарантировать.

person Hans Passant    schedule 08.03.2012