Изненадващ 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>s, които се разпределят на следващия стеков кадър, така че нека изчакаме с този дотогава и да ги свършим всички едно движение, като по този начин нещата се ускоряват по някакъв начин. (???)   -  person Konrad Morawski    schedule 08.03.2012


Отговори (1)


Това е доста стандартно поведение, когато отстранявате грешки в оптимизиран код. Малко вероятно е тук да е така. Вероятно вместо това е грешка в програмата за отстраняване на грешки. Имаше важна пост SP1 актуална корекция за VS2008, която коригира редица проблеми с дебъгерите.

Ще намерите връзката към актуалната корекция в този отговор. Не съм сигурен колко е приложима актуалната корекция за Express Edition, трябва да сте добре, но не мога да го гарантирам.

person Hans Passant    schedule 08.03.2012