如何更改嵌套构造函数的调用顺序(抽象父项之前的子项)

Joh*_*nes 1 c# polymorphism abstract

下面的代码抛出异常,因为在子构造函数之前调用了抽象构造函数.

我需要提供一个抽象类来封装程序不同部分的一些逻辑.但是,我还需要检查抽象成员是否在创建后正确初始化,而子类没有对此有任何影响.

下面的编译示例应该说明我的问题.

using System;

namespace Stackoverflow
{
    class Program
    {
        static void Main(string[] args)
        {
            var x = new Thing(5);
            var y = new Child(x);
        }
    }

    class Child : AbstractParent
    {
        Thing childthing;

        public Child(Thing provided) : base(){
            childthing = provided;
        }

        public override void Initialise(){
            //Exception is thrown here - childthing is still null
            parentthing = childthing.Add(1);
        }
    }

    abstract class AbstractParent
    {
        protected Thing parentthing;

        public AbstractParent(){
            Initialise();
            AssertThingyNotNull();
        }

        private void AssertThingyNotNull(){
            if (parentthing == null) throw new Exception("Waaa");
        }

        public abstract void Initialise();

    }

    class Thing
    {
        private int i;

        public Thing(int i){
            this.i = i;
        }

        public Thing Add(int b){
            i += b;
            return new Thing(i);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑#1:

是否有某种方法可以通过反映到调用者(应该是儿童严谨的创建者?)然后对该调用的结束做出反应来做到这一点?

编辑#2:获取创建孩子的.ctor很容易.操纵方法似乎是不可能的,也是一个坏主意.

        foreach (StackFrame frame in new StackTrace().GetFrames())
        {
            Console.WriteLine(frame.GetMethod().Name);
        }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

基本上你不能.这就是为什么你应该尽可能避免从构造函数中调用虚拟(或抽象)成员的原因 - 你最终可能会遇到运行不完整上下文的代码.在调用基类构造函数之前执行任何变量初始值设定项,但构造函数体中没有任何代码.

如果您需要执行初始化并且只想在派生类构造函数运行时执行此操作,那么只需Initialise从派生类构造函数调用即可.