Почему вызывается финализатор, хотя экземпляр класса не создан?
Вопрос не имеет смысла.Очевидно, экземпляр создан;что завершит финализатор, если не будет создан экземпляр?Вы пытаетесь сказать нам, что в этом финализаторе нет ссылки "this"?
конструктор не был вызван
Конструктор не может быть вызван, потому что соединение конструктора ссылается на поле, тип которого отсутствует.Как можно вызвать тело конструктора, которое нельзя даже соединить?
Вы, кажется, думаете, что только из-за того, что конструктор не может быть вызван, экземпляр не может быть создан.Это не следует логически вообще.Ясно, что должен быть экземпляр до , когда вызывается ctor, потому что ссылка на этот экземпляр передается ему как "this".Таким образом, менеджер памяти создает экземпляр - и сборщик мусора знает, что выделена память - и затем вызывает конструктор.Если вызов конструктора вызывает исключение - или прерывается асинхронным исключением, таким как прерывание потока - там все еще есть экземпляр, известный сборщику мусора, и, следовательно, нуждающийся в финализации, когда он не работает.
Поскольку объект никогда не будет назначен какой-либо живой переменной - это не может быть, так как назначение происходит после ctor, и ctor бросил, когда джиттер попытался его выполнить, - будет определено, что он мертв в следующем нулевом поколенииколлекция.Затем он будет помещен в очередь финализатора, что сделает его живым.
финализатор все еще вызывается (в потоке GC), что в конечном итоге приводит к сбою приложения.
Затем исправьте финализатор так, чтобы он этого не делал.
Помните, что ctor может быть прерван в любое время асинхронным исключением, таким как прерывание потока.Вы не можете полагаться на любой инвариант объекта, поддерживаемого в финализаторе.Финализаторы - очень странный код;Вы должны предположить, что они могут работать в произвольном порядке в произвольных потоках с произвольно плохим состоянием объекта. Вы должны написать чрезвычайно защитный код внутри финализатора.
Если я установлю точку останова в конструкторе Foo (после удаления dll бара), он не попадет.
Правильно.Как я уже сказал, тело конструктора не может быть соединено.Как вы могли бы достичь точки останова в методе, который даже не может быть объединен?
Это означает, что если бы я установил оператор в конструкторе, который создает критический ресурс (до обновления Bar), он бы нене будет выполнено, следовательно, нет необходимости вызывать финализатор.
Независимо от того, вы думаете, что нужно вызвать финализатор, совершенно не имеет значения длясборщик мусора.Финализатор может иметь другую семантику, кроме простой очистки ресурсов.Сборщик мусора не пытается психически определить намерения разработчика и принять решение о том, нужно ли ему вызвать финализатор или нет. Объект был выделен и имеет финализатор, и вы не подавили финализацию, поэтому он будет завершен. Если вам это не нравится, тогда не делайте финализатор. Вы сделали финализатор, потому что, по-видимому, вы хотели, чтобы все экземпляры объекта были завершены, и поэтому они будут.
Честно говоря, я бы вернулся к вашему базовому сценарию.Идея о том, что вы можете безопасно восстанавливать и продолжать выполнять код в домене приложения, где отсутствуют необходимые библиотеки DLL, кажется мне крайне плохой идеей.Понять это правильно будет очень сложно.