想知道为什么静态构造函数不会在派生类和基类中被击中

时间:2012-08-17 13:39:14

标签: c# .net oop c#-4.0 constructor

这是一个小样本,我正在帮助自己理解使用许多场景的构造函数。我很惊讶为什么这个场景中的静态构造函数根本没有被击中。

我很清楚静态构造函数,甚至已经体验过它们的工作原理。我知道,首先,派生类中的静态构造函数会被命中,然后是基类中的静态构造函数,然后是任何其他构造函数。但我不知道为什么在这个“ENFORCE”基类参数化构造函数工作的特殊情况下,这是静态构造函数没有被击中的原因吗?这是我可以怀疑/理解的,但我可能是错的。但我不能同意这一点,如果这是原因。

这是我现在在VS 2010中工作的代码:

    public class MyBaseClass
    {
        public MyBaseClass(int x)
        {
        }
        static MyBaseClass()
        {
        }
    }

    public class MyDerivedClass : MyBaseClass
    {
        public MyDerivedClass(int i)
            : base(5)
        {
        }
        public MyDerivedClass() : base(2)
        {
        }
        static MyDerivedClass()
        {
        }
        public static void Main()
        {
            new MyDerivedClass();
        }
    }

2 个答案:

答案 0 :(得分:0)

我无法理解为什么series0ne的回答是-ve标记的。通过示例,它详细解释了构造函数的工作原理。

但是,我想指出的一件事是,除了默认/特定构造函数之外,只需要执行新的B()'来调用base和derived的静态构造函数。作为唯一的声明。您不需要声明类型A的变量(或者B的变量),并为其分配以确保调用base的静态构造函数。 (矛盾的评论 - 8月17日的系列0和14:09的12)

以下是一个例子(我写作验证)及其结果:

class A
{
    static A()
    {
        Console.WriteLine("Static A.");
    }

    public A()
    {
        Console.WriteLine("Non-Static A.");
    }
}

class B : A
{
    static B()
    {
        Console.WriteLine("Static B.");
    }

    public B()
    {
        Console.WriteLine("Non-Static B.");
    }
}

void Main()
{
    new B();
}

Static B.
Static A.
Non-Static A.
Non-Static B.

答案 1 :(得分:-1)

编辑 - 不一致和不完整的测试导致我的回答不正确,并且出于明确,简洁和正确答案的兴趣,这篇文章已经完全更新。

静态和非静态构造函数之间的区别:

在第一次使用对象之前会自动调用静态构造函数。它的目的是在自身实例化之前设置自身的任何静态字段/属性/对象(等)。因此,如果我将类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();
    }
}

结果: Hello来自静态A,Hello来自非静态A

由于A在此实例中被实例化一次,因此调用静态A,然后调用非静态A

考虑以下A(x2)的实例化及其结果:

class Program
{
    static void Main(string[] args)
    {
        A instance_1 = new A();
        A instance_2 = new A();

        Console.Read();
    }
}

结果: Hello来自静态A,Hello来自非静态A,Hello来自非静态A

当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 < / p>

最后考虑这个例子......

class Program
{
    static void Main(string[] args)
    {
        A instance_1 = new B();
        B instance_2 = new B();

        Console.Read();
    }
}

结果: Hello来自静态B,Hello来自静态A,Hello来自非静态A,Hello来自非静态B,Hello来自非静态A,Hello来自非静态

同样,A和B是静态构造的(仅一次)但是非静态A和非静态B重复,因为它们现在是B的两个实例,因此对于对象的每个新实例都会发生非静态构造

值得注意的是,似乎静态构造和继承中的非静态构造调用以相反的方式相互作用。 I.E.在最后一个例子中,在静态A之前调用静态B,但是在非静态B之前调用非静态A!