【问题标题】:c# Static constructor and child instancec# 静态构造函数和子实例
【发布时间】:2014-05-09 15:27:50
【问题描述】:

我有以下场景:

Class A
{
    public static  A instance;

    static A()
    {
        if(condition)
        {
            instance = new B();
        }
        else
        {
            instance = new A();
        }

    }

    public A()
    {
        WriteSomething();
    }

    virtual void WriteSomething()
    {
        Console.WriteLine("A constructor called");
    }

}


Class B : A
{
    public B()
    {
        WriteSomething();
    }

    override void WriteSomething()
    {
        Console.WriteLine("B constructor called");
    }

}

问题是,当第一次调用 A.instance 并且如果 conditiontrue 并且调用 B() 构造函数时,由于某些原因我不这样做不明白程序的输出是“A constructor called”。

你能帮忙解释一下吗!

谢谢!

【问题讨论】:

  • 在构造函数中调用虚函数可能是问题所在。为什么不尝试在单独的虚函数中写入输出?
  • condition 值的设置是什么?您能否也将调用代码放入问题中,以便我们可以看到您所做的一切?
  • 这是一个非常大的遗留代码的精简版本,它只是为了举例说明。 reale 代码在虚方法中做了很多事情,不能移动到其他地方。
  • @MattJones 从环境变量中读取条件。调用代码只是调用 A.instance。

标签: c# inheritance constructor static


【解决方案1】:

A 的构造函数将始终首先运行,即使您正在创建新的 B,因为 B 扩展了 A

您还无意中发现了为什么建议您不要将虚函数调用放在构造函数中(至少在 .NET 中)。

http://msdn.microsoft.com/en-us/library/ms182331.aspx

“当调用虚方法时,直到运行时才会选择执行该方法的实际类型。当构造函数调用虚方法时,有可能调用该方法的实例的构造函数尚未执行。 "

【讨论】:

  • 谢谢!我忘记了这个默认的 OOP 行为。
【解决方案2】:

A.WriteSomething() 总是会给你“一个被调用的构造函数” B.WriteSomething() 总是给你总是给你“一个被调用的构造函数”。但是,在构造函数场景中,不会调用 override,您可以使用 new 关键字来创建具有相同名称的新 void。除了虚拟覆盖调用之外,这可以按照您想要的方式工作。但是,上面的代码并不是一个好的实现。

Class A
{
    public static  A instance;

    static A()
    {
        if(condition)
        {
            instance = new B();
        }
        else
        {
            instance = new A();
        }

    }

    public A()
    {
        WriteSomething();
    }

    public static void WriteSomething()
    {
        Console.WriteLine("A constructor called");
    }

}


Class B : A
{
    public B()
    {
        WriteSomething();
    }

    public static new void WriteSomething()
    {
        Console.WriteLine("B constructor called");
    }

}

【讨论】:

  • 你在这里完全改变了他的类的公共接口。而new 关键字,在此处使用的意义上,是一个破坏多态性的非常糟糕的主意。
  • @BrucePierson 我同意,代码本身应该重写。他在构造函数中调用了一个没有意义的虚方法。我只是想举例说明可以做什么。
  • 很公平,但请不要鼓励使用 new - 这是 MS 最糟糕的想法之一。
猜你喜欢
  • 2011-04-19
  • 2014-09-16
  • 2013-03-05
  • 1970-01-01
  • 2015-08-06
  • 2011-05-08
  • 2010-11-11
  • 2014-03-14
  • 1970-01-01
相关资源
最近更新 更多