Как С# знает, когда запускать статический конструктор?
Я не верю, что сгенерированный код будет проверять, был ли класс инициализирован каждый раз, когда он обращается к статическому члену (который включает в себя функции). Я считаю, что проверка каждого доступа была бы неэффективной. Я рассмотрел §17.11 в ECMA 334, и он говорит
Выполнение статического конструктора запускается первым из в домене приложения следующие события:
- Создается экземпляр класса.
- Ссылка на любой из статических членов класса.
Похоже, как определить, когда происходит "первое", не определено. Я не могу придумать, как это сделать, но проверять каждый раз. Как это можно сделать?
Ответы
Ответ 1
Когда у вас есть проблема для решения, хорошей техникой является решение еще более сложной проблемы, так что решение вашей маленькой проблемы решается решением более сложной проблемы.
У CLR гораздо труднее решить проблему: он должен запускать дрожание ровно один раз на каждом методе прямо перед вызовом метода в первый раз. Если CLR может решить эту проблему, то она, очевидно, может решить сравнительно тривиальную под-проблему обнаружения, когда нужно запустить статический ctor.
Возможно, тогда ваш вопрос должен быть "как дрожание знает, когда начинать jit-метод в первый раз?"
Ответ 2
Когда вы создаете код во время выполнения, у вас есть много вариантов. Вы можете вызвать указатель функции NULL, поймать нарушение доступа, запустить статический конструктор, скомпилировать свойство getter, обновить указатель на функцию и продолжить. Или свойство getter вызовет вспомогательную функцию, которая запускает статический конструктор и переписывает код геттера без вызова вспомогательной функции. Или вставьте проверку на каждый доступ к статическому члену, который при ударе перекомпилирует вызывающую функцию с удаленной проверкой.