【问题标题】:C# Call base class' constructor after own constructor?C#在自己的构造函数之后调用基类的构造函数?
【发布时间】:2013-01-11 20:03:01
【问题描述】:

我如何调用基类的构造函数我已经调用了自己的构造函数?

问题是,基类的构造函数调用了一个抽象方法(子类重写),需要访问变量x,在子类的构造函数中初始化?

简短的示例代码:

abstract class BaseClass
{
    protected string my_string;

    protected abstract void DoStuff();

    public BaseClass()
    {
        this.DoStuff();
    }
}

class SubClass : BaseClass
{
    private TextBox tb;

    public SubClass()
        : base()
    {
        this.my_string = "Short sentence.";
    }

    protected override void DoStuff()
    {
        // This gets called from base class' constructor
        // before sub class' constructor inits my_string
        tb.Text = this.my_string;
    }
}

编辑:根据答案,这显然是不可能的。创建 SubClass 的每个对象后,是否有自动调用 this.DoStuff(); 的方法?当然,我可以在子类的构造函数中的所有其他行之后添加this.DoStuff();,但是拥有大约 100 个这样的类,感觉很愚蠢。还有其他解决方案,还是我应该使用手动解决方案?

【问题讨论】:

  • 实际上我不认为你可以,至少不能以一种标准的方式(使用反射也许你可以,但我认为这不是一个好方法)
  • 你不能。想想看 - 你的班级依赖于它的父班级。如何在不先创建父级的情况下创建类的实例?
  • 查看我的编辑。我想我只是在每个子类的构造函数中手动添加一行,没什么大不了的。仍然值得问:-)

标签: c# class inheritance constructor superclass


【解决方案1】:

你不能那样做。但是您可以将主类的启动代码放入单独的初始化方法中。然后,您可以在特定构造函数中调用该方法 > 在构造函数代码之后。

【讨论】:

    【解决方案2】:

    在构造函数实际运行之前你不能构造一个类有什么原因吗?它需要对如何创建派生类承担更大的责任,这可能不是最佳实践,但它似乎有效。

    abstract class BaseClass {
        protected string my_string;
    
        protected abstract void DoStuff();
    
        public BaseClass() {
            this.DoStuff();
        }
    }
    
    class SubClass: BaseClass {
        TextBox tb;
    
        bool Constructed = false;
        void Constructor() {
            if (!Constructed) {
                Constructed = true;
                this.my_string = "Short sentence.";
            }
        }
        public SubClass()
            : base() {
            Constructor();
        }
    
        protected override void DoStuff() {
            Constructor();
            // This gets called from base class' constructor
            // before sub class' constructor inits my_string
            tb.Text = this.my_string;
        }
    }
    

    【讨论】:

      【解决方案3】:

      你不能。

      此外,您通常不应在构造函数中调用virtual 方法。看到这个answer


      根据您的实际代码而不是您编写的简单示例,您可以将值作为基本构造函数和DoStuff 方法的参数传递。例如:

      abstract class BaseClass
      {
          private string my_string;
      
          protected abstract void DoStuff(string myString);
      
          public BaseClass(string myString)
          {
              this.my_string = myString;
              this.DoStuff(this.my_string);
          }
      }
      
      class SubClass : BaseClass
      {
          private TextBox tb;
      
          public SubClass()
              : base("Short sentence.")
          {
          }
      
          protected override void DoStuff(string myString)
          {
              tb.Text = myString;
          }
      }
      

      如果您的实际代码无法实现,那么编写多个DoStuff() 即可。还要记住密封你的 SubClass 类,这样其他人就不能再通过修改 DoStuff 方法来引入错误了。

      【讨论】:

        【解决方案4】:

        我不会在构造函数中调用抽象方法,因为调用该方法的实例的构造函数可能没有执行

        调用虚拟方法时,直到运行时才会选择执行该方法的实际类型。当构造函数调用虚方法时,调用该方法的实例的构造函数可能尚未执行。 要修复违反此规则的行为,请不要从类型的构造函数中调用类型的虚方法。

        http://msdn.microsoft.com/en-us/library/ms182331%28v=vs.80%29.aspx

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-08-18
          • 2018-05-25
          • 1970-01-01
          • 1970-01-01
          • 2021-10-03
          • 2016-07-19
          • 2018-07-21
          • 2013-03-24
          相关资源
          最近更新 更多