2015-04-15 5 views
1

Ранее I posted a question относительно статических инициализаторов и различных выходов между версиями того же кода для отладки и выпуска. Я определил версию Release, выпустив другую продукцию (на самом деле она произвела no) из сборки Debug, потому что параметр DebuggableAttribute позволил оптимизатору JIT исключить вывод в версии Release.Статический инициализатор, который не должен работать

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

using System; 

class Test { 
    static int value = 0; 
    static int a = Initialize("Assigning a"); 
    static int b = Initialize("Assigning b"); 
    static String name = "Fred"; 
    static int c = Initialize("Assigning c"); 

    static int Initialize(String mssg) { 
     ++value; 
     Console.WriteLine("In Initialize() :: {0}, name={1}, returning {2}", mssg, name, value); 
     return value; 
    } // Initialize() 

    static void Main() { 
    }// Main() 
} // class Test 

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

In Initialize() :: Assigning a, name=, returning 1 
In Initialize() :: Assigning b, name=, returning 2 
In Initialize() :: Assigning c, name=Fred, returning 3 

Я прекрасно понимаю, что JITTER способен оптимизировать выходные данные, и я понимаю, почему он это сделает, поэтому я не прошу никого решать различия между сборками Debug и Release.

Что мне пристанет является почемулюбой выход должен появиться в первую очередь. Класс не имеет статического c'tor (который заставил бы запускать статические инициализаторы), ссылок на статические поля вне класса не ссылаются, и класс никогда не создается. То, что я делаю, состоит в том, что результат, созданный этим кодом, никогда не должен производиться, в первую очередь, даже не с помощью сборки Debug, по крайней мере, из моего понимания Language Spec.

Я просматривал куски спецификации C#, и я не могу найти ничего, что говорит, что статические инициализаторы должны запускаться для кода, показанного ниже, независимо от того, скомпилирован ли он для Debug или Release.

Может ли кто-нибудь объяснить, почему этот код должен когда-либо производить вывод и какая часть спецификации языка применяется?

Спасибо.

+0

Попробуйте положить контрольную точку в метод 'Main' и запустить код с прикрепленным отладчиком. Когда он ломается, какие значения вы ожидаете от пяти полей? Попробуйте в режимах отладки и выпуска. Также обратите внимание, что все инициализаторы (назначения, написанные в объявлениях) технически перемещаются в инициализатор статического типа с помощью компилятора C#. Поэтому, даже если в коде C# нет статического конструктора, CLR видит его как статический метод '.cctor'. Тем не менее, среда CLR может запускать или не запускать ее (поле не указывается). Также в режиме выпуска попробуйте версию, в которой вы выписываете 'name' в' Main'. –

ответ

5

поведение определяется как зависит от реализации:

10.4.5.1 Static field initialization

Если статический конструктор (раздел 10.11) существует в классе, выполнение статических полей инициализаторах сразу возникает перед выполнением, что статическое конструктор. В противном случае инициализаторы статического поля выполняются в зависящее от реализации время до первого использования статического поля этого класса.

Я бы предположил, что это облегчает инициализацию их отладки.

+0

Ваша цитата будет соответствовать разделу 10.5.5.1 текущей спецификации. В моем примере кода нет статического c'tor, поэтому это не применяется. Кроме того, использование статических полей также не требуется.Другими словами, ни одно из статических полей не ссылается, поэтому нет необходимости запускать статические инициализаторы. –

+5

Нет необходимости *, но нет необходимости * не * запускать их. Любое время «до первого использования статического поля» разрешено. Поскольку использование статического поля не используется, любое время в порядке. – Blorgbeard

Смежные вопросы