简体   繁体   English

从类构造函数调用抽象方法

[英]Call abstract method from class constructor

I have base class that contain abstract method. 我有包含抽象方法的基类。

public abstract class ClassBase : IClassBase
{
    protected ClassBase()
    {
        ////   some code 
    }

    protected ClassBase(XmlNode settings)
          : this()
    {

    }

    protected abstract void Init(XmlNode settings);
}


public class Class_A : ClassBase
{
    public Class_A(XmlNode settings)
          : this(settings)
    {
        Init(settings);
    }

    protected override void Init(XmlNode settings)
    {


    }
}

Is it ok to call the Init method from Class_A constructor ? 可以从Class_A构造函数中调用Init方法吗?

I try to do it and its run ok - but when the constructor is running the virtual tables are not ready yet and the abstract method are not ready as far as i know. 我试图做到这一点,它运行正常-但据我所知,当构造函数正在运行时,虚拟表尚未准备好,抽象方法尚未准备好。

It's unclear exactly what code you meant, as the code you've given doesn't compile for a couple of reasons. 目前尚不清楚您的代码到底是什么意思,因为给出的代码由于多种原因而无法编译。 Most importantly, did you actually mean to call Init from ClassBase rather than from Class_A ? 最重要的是,您实际上是要从ClassBase而不是从Class_A调用Init吗? If not, it seems pointless making Init abstract. 如果没有,将Init抽象化似乎毫无意义。 This answer assumes you did meant that. 该答案假设您确实这样做。

Is it ok to call the Init method from Class_A constructor ? 可以从Class_A构造函数中调用Init方法吗?

It's valid - but it's not usually a good idea. 这是有效的 -但这通常不是一个好主意。

It's not a matter of the "virtual tables" no being created - that's fine, and it will execute Class_A.Init . 这与不创建“虚拟表”无关紧要-很好,它将执行Class_A.Init An object is created as an instance of its eventual type immediately. 将立即创建一个对象作为其最终类型的实例。 The problem is that you're calling a method on the Class_A instance before its constructor has had a chance to execute. 问题是您要在Class_A实例构造函数有机会执行之前调用该方法。 That means it may be in an unexpected state - normal preconditions may not hold, for example. 这意味着它可能处于意外状态-例如,正常的前提条件可能不成立。

Example

public class Class_A : ClassBase
{
    private readonly string text;

    public Class_A(XmlNode settings, string text)
        : base(settings) // Which calls Init(settings) as per intro paragraph
    { 
        if (text == null)
        {
            throw new ArgumentNullException("text");
        }
        this.text = text;           
    }

    protected override void Init(XmlNode settings)
    {
        // In here, text is still null... even though it can't be in any
        // other method.
    }
}

Just occasionally, it's the least worst solution, but in that case: 偶尔,这是最糟糕的解决方案,但在这种情况下:

  • Really make sure there isn't a better solution 确实确保没有更好的解决方案
  • Document it very clearly 文件就可以清楚
  • Avoid calling the method from anywhere else, as it's often odd to code an implementation which is appropriate in both "I'm half way through initialization" and "I'm fully initialized" states. 避免从其他任何地方调用该方法,因为编写一个适合在“我已完成初始化一半”和“我已完全初始化”状态的实现通常很奇怪。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM