编辑 - 不一致和不完整的测试导致我的答案不正确,为了清晰、简洁和正确的答案,这篇文章已经完全更新。
静态和非静态构造函数的区别:
在第一次使用对象之前会自动调用静态构造函数。它的目的是在自身的任何实例化发生之前设置自身的任何静态字段/属性/对象(等)。因此,如果我将类 A 定义为具有静态构造函数,并创建 A 的实例,则静态构造函数将在实例化 A 之前执行。
例如,假设我构造了 A 的两个实例,我只看到 A 的静态构造函数一次......为什么!?因为对于特定的对象类型,静态构造只需要发生一次。除此之外,执行静态构造毫无意义,因为它已经完成了!
考虑本练习的以下代码:
public class A
{
static A()
{
Console.WriteLine("Hello from static A");
}
public A()
{
Console.WriteLine("Hello from non-static A");
}
}
public class B : A
{
static B()
{
Console.WriteLine("Hello from static B");
}
public B() : base() //explicit so you know B() will call A()
{
Console.WriteLine("Hello from non-static B");
}
}
考虑以下 A 的实例化及其结果:
class Program
{
static void Main(string[] args)
{
A instance_1 = new A();
Console.Read();
}
}
结果: 来自静态 A 的 Hello,来自非静态 A 的 Hello
由于 A 在本例中被实例化一次,因此调用静态 A,然后调用非静态 A
考虑以下 A (x2) 的实例化及其结果:
class Program
{
static void Main(string[] args)
{
A instance_1 = new A();
A instance_2 = new A();
Console.Read();
}
}
结果: 来自静态 A 的 Hello,来自非静态 A 的 Hello,来自非静态 A 的 Hello
由于 A 被实例化了两次,因此静态 A 被调用一次(因为静态 A 是一次性操作),非静态 A 被调用两次以创建 A 的两个实例
考虑从 A 分配给 B 的以下实例及其结果:
class Program
{
static void Main(string[] args)
{
A instance_1 = new B();
Console.Read();
}
}
结果: 来自静态 B 的 Hello,来自静态 A 的 Hello,来自非静态 A 的 Hello,来自非静态 B 的 Hello
现在 A 和 B 都是静态构造的(仅第一次),因为 B 是 A 的后代。这也很明显,非静态 B 调用非静态 A。因为 A 是祖先或 B
最后考虑这个例子......
class Program
{
static void Main(string[] args)
{
A instance_1 = new B();
B instance_2 = new B();
Console.Read();
}
}
结果: 来自静态 B 的问候,来自静态 A 的问候,来自非静态 A 的问候,来自非静态 B 的问候,来自非静态 A 的问候,来自非静态 B 的问候
同样,A 和 B 是静态构造的(仅一次),但非静态 A 和非静态 B 重复,因为它们现在是 B 的两个实例,因此对于对象的每个新实例都会发生非静态构造
值得注意的是,静态构造和非静态构造调用在继承中的工作方式似乎相反。IE 在最后一个例子中,静态 B 在静态 A 之前被调用,但是非静态 A 在非静态 B 之前被调用!