Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.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# 在.NET中,类可以有虚拟构造函数吗?_C#_.net_Oop - Fatal编程技术网

C# 在.NET中,类可以有虚拟构造函数吗?

C# 在.NET中,类可以有虚拟构造函数吗?,c#,.net,oop,C#,.net,Oop,类可以有虚拟构造函数吗 如果是,为什么需要它?否,类不能有虚拟构造函数 使用虚拟构造函数是没有意义的。在C#中构造对象的顺序是首先构造派生类,因此始终调用派生构造函数,因为要调用的类在构造时是众所周知的 另一件事是,如果你真的输入了这段代码,你很快就会发现它毫无意义 如果你有: public class BaseClass { public virtual BaseClass() { } } 然后 public class InheritedClass : BaseC

类可以有虚拟构造函数吗


如果是,为什么需要它?

否,类不能有虚拟构造函数

使用虚拟构造函数是没有意义的。在C#中构造对象的顺序是首先构造派生类,因此始终调用派生构造函数,因为要调用的类在构造时是众所周知的

另一件事是,如果你真的输入了这段代码,你很快就会发现它毫无意义

如果你有:

public class BaseClass 
{
    public virtual BaseClass()
    {
    }
}
然后

public class InheritedClass : BaseClass
{
    //overrides baseclass constructor but why would you do this given that the     
    //constructor is always going to be called anyway??
    public override InheritedClass()
    {
    }
}

声明某个虚拟对象意味着它可以被当前类的子类重写。但是,在实例化类时会调用构造函数。那时,您无法创建相关类的子类,因此永远不需要将构造函数声明为虚拟构造函数。

不是直接声明,但经典的四人组模式工厂方法通过将实例化延迟到子类来实现某种虚拟构造函数。

不,它是如何工作的?从基类派生子类时,必须调用层次结构中的所有构造函数。将构造函数设为虚拟将意味着另一种情况

当您使用工厂模式时,可以将其描述为具有类似虚拟构造函数的行为。想象一下这个场景:

class AnimalFactory
{
    virtual Animal CreateAnimal( return new Animal("Cow"); );
}
此工厂的默认行为是创建奶牛。但是如果我们创建一个派生类:

class DogFactory : AnimnalFactory
{
    override Animal CreateAnimal( return new Animal("Dog"); );
}

我们现在正在创造狗。当然,这不是真正的虚拟构造函数(这是不可能的),这是虚拟构造。

如果我们看看构造器和虚拟这个词的定义,我们会得出一个逻辑结论,构造器不可能是虚拟的

根据定义,虚拟方法是基于接收器的运行时类型分析而不是接收器的编译时静态类型分析而调度的方法

构造函数是在创建特定类型的新实例时调用的方法

由于新创建的对象的运行时类型始终与其编译时类型相同(*),因此不需要虚拟构造函数:运行时调度将始终选择与静态调度相同的方法,那么为什么还要费心改变呢


(*)这并不完全正确;有一些涉及COM互操作的场景,其中构造的运行时类型不是编译时类型。在遗留互操作代码的世界中,许多事情都很奇怪。

仅供参考,当人们要求使用虚拟构造函数时,一个非常好的模式是

在.NET中,我们有几个IoC容器,如ObjectBuilder、Unity、MEF、Spring.NET。Java中有Spring、Tapestry和其他很多东西(可能会炫耀我的Java能力)


IMHO IoC是让OO实现其承诺的因素。

关于调用派生类中的基构造函数:是否会有一个链正常地指向基,例如“public override InheritedClass():base()”。@paul ruane:你是对的,但我想说的是重写基类是多余的,因为要么显式地使用base()引用它,要么不显式地使用base()引用它,并且在构造对象时会调用它,所以拥有虚拟构造函数是无点的。拥有虚拟构造函数是非常有意义的。这是各种构建器模式在不直接支持它的语言中实现的。我不同意构造函数的执行顺序,即先派生,然后基。在c#中,基类构造函数总是在派生类构造函数之前被调用。Vishal,你是对的。初始化器从最派生的类运行到基类,构造函数从基类运行到最派生的类。真的吗?在Delphi中,虚拟构造函数与类引用类型(“CLASS OF”)一起出现是很常见的。C程序员不了解的一个概念:-)。是的-我知道问题是C#,但是虚拟构造函数的概念在所有语言中都不是一个矛盾的术语:-)。关于Delphi中的虚拟构造函数,您是对的,但是,这是语言规范的结果。您声明了一个方法并声明它将是一个构造函数。方法名与创建任何类型的类型无关。这是理解为什么虚构造函数的概念通常是无效的关键。您可以声明工厂方法,甚至可以重写它。因此,方法是扭转德尔福有虚拟方法,可以命名为构造函数,但它没有结构,它本身是一个构造函数,像其他C语言一样。