1

假设我有一个具有 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)
{
    ....
} 

我知道 Resolver 可以通过它选择的任何方式生成程序集。在我的应用程序的情况下,它做了一个

Assembly.GetExecutingAssembly().GetManifestResourceStream(name);

其中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 的。这会,也许?导致Fusion错误?

有人有任何见识吗?

这不是一个非常关键的问题,因为我可以重新设计类来避免这个问题,删除所有依赖于嵌入式程序集的实例变量。但我想理解它。

4

1 回答 1

6

你是对的,就顺序而言。

静态构造函数首先运行,然后是非参数化构造函数,然后是参数化构造函数。

JIT 时间应该不是问题。CLR 保证您的静态构造函数将在构造任何实例之前完成。

但是,程序集解析发生在您的静态构造函数触发之前。运行时需要在调用任何静态构造之前解析程序集(及其依赖项)。这就是你遇到这个问题的原因。

于 2009-08-12T23:38:15.617 回答