Ранее 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.
Может ли кто-нибудь объяснить, почему этот код должен когда-либо производить вывод и какая часть спецификации языка применяется?
Спасибо.
Попробуйте положить контрольную точку в метод 'Main' и запустить код с прикрепленным отладчиком. Когда он ломается, какие значения вы ожидаете от пяти полей? Попробуйте в режимах отладки и выпуска. Также обратите внимание, что все инициализаторы (назначения, написанные в объявлениях) технически перемещаются в инициализатор статического типа с помощью компилятора C#. Поэтому, даже если в коде C# нет статического конструктора, CLR видит его как статический метод '.cctor'. Тем не менее, среда CLR может запускать или не запускать ее (поле не указывается). Также в режиме выпуска попробуйте версию, в которой вы выписываете 'name' в' Main'. –