Предположим, у меня есть класс с 3 конструкторами, конструктор по умолчанию (без аргумента), параметризованный конструктор и статический конструктор. например:Заказ конструкторов для класса C#: параметризованный, по умолчанию и статический?
public MyClass() { ... }
public MyClass(string arg) : this() { ... }
static MyClass() { ... }
Предположим, что я вызываю параметризованный конструктор, в каком порядке выполняются эти конструкторы?
Я думал, что это статичный, затем параметризованный, а затем по умолчанию. Но ... мой опыт не согласен с этим.
У меня есть приложение, в которое встроена ссылка DLL в качестве ресурса. Во время выполнения, приложение регистрирует сборки распознаватель через
static MyClass()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Resolver);
}
где метод Резольвера определяется следующим образом:
static System.Reflection.Assembly Resolver(object sender, ResolveEventArgs args)
{
....
}
я понял, что распознаватель может производить сборку, так, как это штопка хорошо выбирает , В случае моего приложения, это делает имя
Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
где это имя вложенного ресурса. Затем прочитайте все байты этого ресурса и сделайте Assembly.Load (byte []) в блоке прочитанных байтов.
Это может показаться вам странным, но это работает.
Вы могли бы сказать: Почему в мире вы бы вставляли сборку, а не только ILMerge? Хороший вопрос. Я думаю, что мне нужно внедрить, потому что встроенная сборка подписана, и у меня нет ключа для повторной подписывания объединенной сборки. Поэтому я вставляю.
Проблема заключается в следующем: предположим, что я объявляю переменную члена частного экземпляра класса, которая имеет тип, определенный во встроенной сборке. В моем случае это перечисление, и я также инициализирую значение этого перечисления.
Теперь, если статический конструктор уже запущен, тогда инициализатор этого частного члена не будет работать. Но я вижу ошибку «файл не найден» - ваша основная ошибка Fusion.
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'MyApp, Version=1.1.4.1, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c' or one of its dependencies. The system cannot find the file specified.
File name: 'MyApp, Version=1.1.4.1, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c'
WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value[HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
Если я удалю переменную частного экземпляра, то я не получу ошибку Fusion.
Я могу использовать переменные этого типа или любой другой тип, определенный во встроенной сборке, позже, если они не инициализируются как переменные экземпляра-члена в классе. Я могу использовать типы в методе экземпляра, без проблем.
Написав это, я думаю, что, возможно, придумал ответ на свой вопрос. Возможно, это проблема времени JIT: возможно, конструкторы экземпляров JIT'd перед запуском статического конструктора. Это может быть? приведет к ошибке Fusion?
У кого-нибудь есть понимание?
Это не очень важная проблема, потому что я могу перепроектировать класс, чтобы избежать проблемы, удалив все переменные экземпляра, зависящие от встроенной сборки. Но я хотел бы это понять.
Не совсем понятно, что вы подразумеваете под «классом» в приведенном выше, это во встроенной сборке или в классе загрузки? Это может иметь значение, поскольку у вас могут быть упорядочивающие и круговые проблемы со статическими ctors. –
«класс» в коде, который я пишу, который будет потреблять типы во внешней сборке. Я не знаю, где это неясно в вопросе выше. Если бы я знал, что могу изменить Q, чтобы уточнить. – Cheeso