Как C # знает, когда запускать статический конструктор? - PullRequest
12 голосов
/ 18 февраля 2012

Я не верю, что сгенерированный код будет проверять, был ли класс инициализирован каждый раз, когда он обращается к статическому члену (который включает функции). Я считаю, что проверка каждого доступа была бы неэффективной. Я посмотрел на §17.11 в ECMA 334 и там написано

Выполнение статического конструктора запускается первым из в домене приложения происходят следующие события:

  • Экземпляр класса создан.
  • Ссылка на любой статический член класса.

Похоже, как выяснить, когда происходит «первое», не определено. Я не могу придумать способ сделать это, кроме как проверять каждый раз. Как это можно сделать?

Ответы [ 2 ]

16 голосов
/ 18 февраля 2012

Если у вас есть проблема, которую нужно решить, хороший метод: решить еще более сложную проблему, такую, что решение вашей маленькой проблемы решается путем решения более сложной проблемы.

У CLR гораздо сложнее решить проблему: он должен запускать джиттер для каждого метода ровно один раз перед тем, как метод вызывается в первый раз. Если CLR может решить эту проблему, то он, очевидно, может решить сравнительно тривиальную подзадачу определения того, когда должен работать статический ctor.

Возможно, тогда ваш вопрос должен звучать так: «Как джиттер узнает, когда выполнять метод в первый раз?»

5 голосов
/ 18 февраля 2012

Когда вы генерируете код во время выполнения, у вас есть много вариантов. Вы можете вызвать нулевой указатель на функцию, отследить нарушение прав доступа, запустить статический конструктор, скомпилировать свойство get, обновить указатель функции и продолжить. Или пусть свойство getter вызывает вспомогательную функцию, которая запускает статический конструктор и переписывает код получателя без вызова вспомогательной функции. Или вставьте проверку при каждом доступе к статическому члену, чтобы при ударе перекомпилировать вызывающую функцию с удаленной проверкой.

...