РЕДАКТИРОВАТЬ: Хотя оригинальный ответ ниже все еще точен, похоже, что это смесь отладочной информации и оптимизации, которая имеет значение здесь.
Из моих экспериментов:
Compiler flags Result
/o+ /debug- Finalizer runs
/o+ /debug+ Finalizer runs
/o- /debug- Finalizer runs
/o- /debug+ Finalizer does *not* run
Финализатор все еще вызывается на моем компьютере при компиляции в командной строке с /o+
.Я предполагаю, что вы работаете в отладчике, который меняет поведение GC.Без отладчика GC будет собирать все, что может доказать, что он никогда не будет прочитан. С отладчиком я считаю, что сборщик мусора не будет собирать объекты, на которые еще есть ссылки в стеке, даже если нет кода для чтения рассматриваемых переменных.
Теперь с инициализатором объекта код компилятора включает дополнительную ссылку на стек.Эта строка:
Zombie z = new Zombie { Name = "Guy" };
эффективно:
Zombie tmp = new Zombe();
tmp.Name = "Guy";
Zombie z = tmp;
Присвоение z
выполняется только после , все свойства были установлены.
Я предполагаю, что переменная tmp
поддерживает объект живым.