在 .NET 中,一个类可以有虚拟构造函数吗?
Posted
技术标签:
【中文标题】在 .NET 中,一个类可以有虚拟构造函数吗?【英文标题】:In .NET can a class have virtual constructor? 【发布时间】:2011-04-08 18:11:53 【问题描述】:类可以有虚拟构造函数吗?
如果是,为什么需要它?
【问题讨论】:
【参考方案1】:仅供参考,当人们要求虚拟构造函数时,一个非常好的模式是InversionOfControl
在 .NET 中,我们有几个 IoC 容器,例如 ObjectBuilder、Unity、MEF、Spring.NET。在 Java 中(有炫耀我的 Java 无能的风险)有 Spring、Tapestry 和许多其他。
恕我直言,IoC 是 OO 兑现承诺的原因。
【讨论】:
【参考方案2】:根据定义,虚拟方法是根据接收方的运行时类型分析而不是接收方的编译时静态类型分析来调度的方法。
构造函数是在创建特定类型的新实例时调用的方法。
由于新创建对象的运行时类型与其编译时类型总是相同 (*),因此不需要虚拟构造函数:运行时调度总是选择相同的方法作为静态调度,何必费心去改变呢?
(*) 这并不完全正确;在某些涉及 COM 互操作的场景中,构造的运行时类型不是编译时类型。在遗留互操作代码的世界中,很多事情都很奇怪。
【讨论】:
【参考方案3】:不,类不能有虚拟构造函数。
拥有一个虚拟构造函数是没有意义的。在 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()
【讨论】:
关于在派生类中调用基类构造函数:不会有一个链到基类正常,例如'public override InheritedClass() : base()'。 @paul ruane:你是对的,但我想说的是重写基类是多余的,因为你要么明确说明它并使用 base( ) 或者你不是,当对象被构造时它会被调用,所以拥有一个虚拟构造函数是没有意义的 拥有虚拟构造函数非常有意义。这就是各种构建器模式在不直接支持它的语言中实现的。 我不同意构造函数的执行顺序,即先Derived,然后Base。在 C# 中,基类构造函数总是在派生类构造函数之前被调用。 维沙尔,你是对的。初始化程序从大多数派生类运行到基类,构造函数从基类运行到最派生类。【参考方案4】:如果我们查看构造函数和虚拟这个词的定义,我们会得出一个合乎逻辑的结论,即构造函数不能是虚拟的。
【讨论】:
真的吗?在 Delphi 中,虚拟构造函数与 CLASS REFRENCE TYPES(“CLASS OF不,它是如何工作的?当您从基类派生子类时,必须调用层次结构中的所有构造函数。将构造函数设为虚拟则意味着其他情况。
当您使用工厂模式时,可能会被描述为具有类似虚拟构造函数的行为。想象一下这种情况:
class AnimalFactory
virtual Animal CreateAnimal( return new Animal("Cow"); );
这个工厂的默认行为是创建奶牛。但是如果我们创建一个派生类:
class DogFactory : AnimnalFactory
override Animal CreateAnimal( return new Animal("Dog"); );
我们现在正在创造狗。当然这不是真正的虚构造函数(这是不可能的),这是虚构造函数。
【讨论】:
【参考方案6】:不是直接的,但是经典的四人帮模式工厂方法通过将实例化推迟到子类来实现相当于某种虚拟构造函数。
【讨论】:
【参考方案7】:声明一些虚拟的东西意味着它可以被当前类的子类覆盖。但是,在实例化类时会调用构造函数。那时您不能创建相关类的子类,因此永远不需要声明构造函数 virtual。
【讨论】:
以上是关于在 .NET 中,一个类可以有虚拟构造函数吗?的主要内容,如果未能解决你的问题,请参考以下文章
我可以从 C# 中同一类的另一个构造函数调用重载构造函数吗?