2012-02-17 2 views
12

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

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

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

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

+3

Связанный, для статического случая: http://csharpindepth.com/Articles/General/Beforefieldinit.aspx - нетривиальный –

+0

Разве это не вопрос установки указателя функции в другое место после первого вызов? Сначала он указывает на загрузчик классов или что-то еще, а затем в теле функции ... – user1096188

+1

@Marc: Это обсуждается при вызове статического конструктора ПЕРЕД первым доступом к статическому члену, а не с тем, как обнаружен первый доступ , –

ответ

5

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

16

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

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

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

+0

Интересно. Я просто предположил, что JIT на не встроенных системах просто сжимает все сразу и поддерживает загрузку новых dll. Я предположил, что встраиваемые системы используют досрочное усложнение. Плохое предположение, особенно когда вступает в игру большой код. +1 для мыслей –

+1

@ acidzombie24 на самом деле, некоторые встроенные системы вообще не JIT/AOT ** ** - Micro Framework - это интерпретатор IL (пересекает пальцы, которые у меня не получили назад) –

+0

и некоторые таких систем.Net Compact Framework JIT - только основные вещи, например. get property - вызов функции –