首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >想知道为什么在派生类和基类中没有命中静态构造函数

想知道为什么在派生类和基类中没有命中静态构造函数
EN

Stack Overflow用户
提问于 2012-08-17 21:39:14
回答 2查看 1.1K关注 0票数 1

这是我帮助自己理解构造函数的一个小示例。我很惊讶为什么这个场景中的静态构造函数根本没有被命中。

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

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

代码语言:javascript
运行
复制
    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();
        }
    }
EN

回答 2

Stack Overflow用户

发布于 2017-08-01 16:30:23

我不明白为什么series0ne的答案被标记为-ve。这是对构造器如何工作的详细解释,并举例说明。

然而,我想指出的一件事是,除了默认/特定的构造函数之外,还可以通过简单地将'new B()‘作为唯一的语句来调用base和派生的静态构造函数。你不需要声明一个类型为A(或B)的变量并赋值给它,以确保调用base的静态构造函数。(矛盾的评论- series0ne 8月17 '12 14:09)

下面是一个例子(我写这个例子是为了验证)及其结果:

代码语言:javascript
运行
复制
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.
票数 0
EN

Stack Overflow用户

发布于 2012-08-17 21:53:57

编辑-不一致和不完整的测试导致了我的错误答案,为了得到清晰、简洁和正确的答案,这篇文章已经完全更新了。

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

在第一次使用对象之前,会自动调用静态构造函数。它的目的是设置任何静态字段/属性/对象(等)。在自身的任何实例化发生之前。因此,如果我将类A定义为具有静态构造函数,并创建A的一个实例,则静态构造函数将在A被实例化之前执行。

例如,我构造了A的两个实例,我只看到A once...why的静态构造函数!?因为对于特定的对象类型,静态构造只需要发生一次。除此之外,执行静态构造是没有意义的,因为它已经完成了!

考虑本练习的以下代码:

代码语言:javascript
运行
复制
    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的以下实例化及其结果:

代码语言:javascript
运行
复制
class Program
{
    static void Main(string[] args)
    {
        A instance_1 = new A();

        Console.Read();
    }
}

结果:来自静态A的问候,来自非静态A的问候

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

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

代码语言:javascript
运行
复制
class Program
{
    static void Main(string[] args)
    {
        A instance_1 = new A();
        A instance_2 = new A();

        Console.Read();
    }
}

结果:来自静态A的问候,来自非静态A的问候,来自非静态A的问候

由于A被实例化两次,因此静态A被调用一次(因为静态A是一次性操作),而非静态A被调用两次以创建A的两个实例

考虑分配给from A的B的以下实例化及其结果:

代码语言:javascript
运行
复制
    class Program
    {
        static void Main(string[] args)
        {
            A instance_1 = new B();

            Console.Read();
        }
    }

结果:来自静态B的问候,来自静态A的问候,来自非静态A的问候,来自非静态B的问候

现在A和B都是静态构造的(仅第一次),因为B是A的后代。这在非静态B调用非静态A时也很明显,因为A是祖先或B

最后考虑这个例子...

代码语言:javascript
运行
复制
class Program
{
    static void Main(string[] args)
    {
        A instance_1 = new B();
        B instance_2 = new B();

        Console.Read();
    }
}

结果:来自静态B的问候、来自静态A的问候、来自非静态A的问候、来自非静态B的问候、来自非静态A的问候

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

也许还值得注意的是,继承中的静态构造和非静态构造调用似乎是以相反的方式工作的。也就是说,在最后一个例子中,静态B在静态A之前被调用,而非静态A在非静态B之前被调用!

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12006936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档