Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#静态构造函数和子实例_C#_Inheritance_Constructor_Static - Fatal编程技术网

c#静态构造函数和子实例

c#静态构造函数和子实例,c#,inheritance,constructor,static,C#,Inheritance,Constructor,Static,我有以下情况: Class A { public static A instance; static A() { if(condition) { instance = new B(); } else { instance = new A(); } } public A() { Wri

我有以下情况:

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()构造函数,出于某些原因,我不认为程序的输出是“调用的构造函数”

你能帮我解释一下吗


谢谢大家!

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

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

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

a.WriteMething()将始终为您提供“名为”B.WriteMething()的构造函数”将始终给你将始终给你“一个构造函数调用”。但是,在构造函数场景中,不会调用覆盖,您可以使用new关键字创建具有相同名称的新空。除了虚拟覆盖调用之外,它还可以按照您想要的方式工作。但是,上面的代码不是一个好的实现

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");
    }

}

在构造函数中调用虚函数可能是个问题。为什么不尝试在一个单独的虚拟函数中写入输出?设置
条件的值是什么?你能不能把调用代码放到问题中,这样我们就可以看到你所做的一切?这是一个非常大的遗留代码的精简版本,只是为了举例说明。reale代码在virtual方法中做了很多事情,不能移动到其他地方。@MattJones条件是从环境变量读取的。调用代码只调用了一个实例。谢谢!我已经了解了这个默认的OOP行为。你已经完全改变了他的类的公共接口。在这里使用的
new
关键字是一个非常糟糕的主意,它破坏了多态性。@BrucePierson我同意,代码本身应该重新编写。他在构造函数中调用了一个虚拟方法,这毫无意义。我只是想举一个可以做的例子。这很公平,但请不要鼓励使用
新的
——这是微软最糟糕的想法之一。