假设我有一个类,有3个构造函数、一个默认(无参数)构造函数、一个参数化构造函数和一个静态构造函数。这样地:
public MyClass() { ... }
public MyClass(string arg) : this() { ... }
static MyClass() { ... }
假设我调用参数化构造函数,这些构造函数的执行顺序是什么?
我认为它是静态的,然后是参数化的,然后是默认的。但是…我的经验不同意这一点。
背景:我有一个将引用的dll嵌入为资源的应用程序。在运行时,应用程序注册一个
集解析器
通过
static MyClass()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Resolver);
}
其中resolver方法的定义如下:
static System.Reflection.Assembly Resolver(object sender, ResolveEventArgs args)
{
....
}
我知道分解器可以以它所能选择的任何方式产生一个组件。在我的应用程序中,它可以
Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
哪里
名称
是嵌入资源的名称。然后读取该资源的所有字节,并对所读取的字节块执行assembly.load(byte[])。
一开始你可能觉得这很奇怪,但它起作用了。
你可能会说,
为什么你要嵌入一个程序集,而不仅仅是ilmerge?
好问题。我认为我需要嵌入,因为嵌入的程序集已签名,并且我没有重新对合并的程序集签名的键。所以我嵌入了。
问题是:假设我在类上声明了一个私有实例成员变量,该变量属于在嵌入程序集中定义的类型。在我的例子中,它是一个枚举,我还初始化了该枚举的值。
现在,如果静态构造函数已经运行,那么该私有成员上的初始值设定项将不会有问题运行。但我看到的是一个“找不到文件”的错误——你的基本融合错误。
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].
如果我移除私有实例变量,那么就不会得到融合错误。
我可以使用该类型的变量,或者嵌入程序集中定义的任何其他类型,
后来
,只要它们没有初始化为类中的成员实例变量。我可以在实例方法中使用这些类型,没问题。
把这个写下来,我想我可能已经想出了我自己问题的答案。可能这是一个JIT时间问题:可能实例构造函数在静态构造函数运行之前正在进行JIT。可能会这样?导致融合错误?
有人有什么见解吗?
这不是一个很大的关键问题,因为我可以重新设计类以避免这个问题,删除依赖于嵌入程序集的所有实例变量。但我想理解。