1

这是我帮助自己理解处理许多场景的构造函数的一个小示例。我很惊讶为什么这个场景中的静态构造函数根本没有受到影响。

我非常了解静态构造函数,甚至体验过它们的工作方式。我知道,首先是派生类中的静态构造函数被命中,然后是基类中的静态构造函数,然后是任何其他构造函数。但是我不知道为什么在这种特殊情况下,我“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();
        }
    }
4

2 回答 2

0

我不明白为什么 series0ne 的答案是 -ve 标记的。这是对构造函数如何工作的详细解释,并附有示例。

但是,我想指出的一件事是,除了默认/特定构造函数之外,还将调用基类和派生类的静态构造函数,只需将“new B()”作为唯一语句即可。您无需声明 A 类型(或 B 类型)的变量并分配给它以确保调用 base 的静态构造函数。(矛盾的评论 - series0ne 2012 年 8 月 17 日 14:09)

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

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.
于 2017-08-01T08:30:22.527 回答
-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();
    }
}

结果: 来自静态 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 之前被调用!

于 2012-08-17T13:53:57.217 回答