Che*_*eso 0 .net constructor class-design fusion
假设我有一个包含3个构造函数的类,一个默认(无参数)构造函数,一个参数化构造函数和一个静态构造函数.像这样:
public MyClass() { ... }
public MyClass(string arg) : this() { ... }
static MyClass() { ... }
Run Code Online (Sandbox Code Playgroud)
假设我调用参数化构造函数,这些构造函数以什么顺序执行?
我认为它是静态的,然后参数化,然后默认.但是......我的经历并不同意.
背景:我有一个应用程序嵌入引用的DLL作为资源.在运行时,应用程序通过注册程序集解析程序
static MyClass()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Resolver);
}
Run Code Online (Sandbox Code Playgroud)
Resolver方法定义如下:
static System.Reflection.Assembly Resolver(object sender, ResolveEventArgs args)
{
....
}
Run Code Online (Sandbox Code Playgroud)
我知道解析器可以按照它选择的任何方式生成装配.在我的应用程序的情况下,它做了一个
Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
Run Code Online (Sandbox Code Playgroud)
其中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].
Run Code Online (Sandbox Code Playgroud)
如果我删除私有实例变量,那么我没有得到Fusion错误.
我可以使用该类型,或在嵌入式组件限定,任何其它类型的变量后,只要它们不作为在类成员的实例变量初始化上.我可以在实例方法中使用类型,没问题.
写这篇文章,我想我可能已经想出了我自己的问题的答案.也许这是一个JIT计时问题:在静态构造函数运行之前,实例构造函数可能正在进行JIT.也许吧?导致Fusion错误?
谁有任何见解?
这不是一个非常重要的问题,因为我可以重新设计类来避免这个问题,删除所有依赖于嵌入式程序集的实例变量.但我想了解它.
就订单而言,你是对的.
首先运行静态构造函数,然后运行非参数化构造函数,然后运行参数化构造函数.
JIT时间不应成为问题.CLR保证在构造任何实例之前完成静态构造函数.
但是,在静态构造函数触发之前,会发生程序集解析.运行时需要在调用任何静态构造之前解析程序集(及其依赖项).这就是你遇到这个问题的原因.
归档时间: |
|
查看次数: |
1749 次 |
最近记录: |