【问题标题】:Construct object in base class constructor?在基类构造函数中构造对象?
【发布时间】:2013-04-09 09:56:28
【问题描述】:

我目前有以下代码模式,我在通用类 MyClass 的构造函数中初始化 MyThing 类型的特定对象。但是,在一些特定的派生类示例(例如 MySpecialClass)中,我想使用 MyThing 的派生版本,我称之为 MySpecialThing。

public class MyClass
{
    public MyClass()
    {
        this.MyThing = new MyThing();
    }

    public MyThing MyThing { get; set; }
}

public class MySpecialClass : MyClass
{
    public MySpecialClass()
    {
        this.MyThing = new MySpecialThing();
    }
}

我的问题是这是否是不好的做法,因为实际上 MyThing 属性被初始化了两次,一次在基类中,一次在派生类中。显然,我可以将一个布尔值传递给基类构造函数,或者告诉它不要打扰初始化 MyThing,但这可能有点矫枉过正......

【问题讨论】:

    标签: c# oop constructor


    【解决方案1】:

    这取决于创建 MyThing 的开销。

    不过,有一个解决办法:

    您可以添加一个接受 MyThing 类型参数的受保护基类构造函数,并在那里对其进行初始化。

    public class MyClass
    {
        private readonly MyThing myThing;
    
        public MyClass(): this(new MyThing())
        {
        }
    
        protected MyClass(MyThing thing)
        {
            Contract.Requires(thing != null);
            myThing = thing;
        }
    
        public MyThing MyThing { get { return myThing; } }
    }
    
    public class MySpecialClass : MyClass
    {
        public MySpecialClass(): base(new MySpecialThing())
        {
        }
    }
    

    我认为这比在公共基类构造函数中添加布尔值更好。

    即使构建 MyThing 的开销很小,我也认为这样做是值得的,因为它更清楚地表达了设计。

    我还稍微改变了设计,使myThing 成为只读字段,以表达它应该只在构建时设置的意图。 (如果不是这种情况,并且您希望它稍后可设置,则必须恢复为公共属性设置器。)

    【讨论】:

    • 您甚至可以在基类中委托默认构造函数:public MyClass() : this(new MyThing()){},但这只是一个见仁见智的问题 :) 总的来说,+1。
    • 很好的答案,谢谢。关于使其成为只读的好主意。我通常是只读变量的粉丝,只是烦人的是没有类似于 { get; 的速记。放; } 表示只读属性和字段的符号。
    • 我确实在几年前向 Microsoft Connect 添加了一个对“只读”属性的请求,但事实证明存在一些语法和其他问题,这使得它的实现不如我预期的那么简单。 :)
    • 是的,我认为获取值的唯一方法是通过构造函数,并且很难为此定义“隐式”语法。他们可以改为允许对象初始化器语法用于只读变量的构造函数,不知道这是否会引发其他蠕虫。
    【解决方案2】:

    您是否关心性能或可维护性?

    只有在 MyThing 构造函数很昂贵,或者您必须在紧密循环中创建大量对象时,性能问题才有意义。

    我会更担心可维护性,因为您有多个初始化对象状态的位置。您可以将它从派生类传递给受保护的基类构造函数,并具有默认使用 MyThing 的默认构造函数

    【讨论】:

      【解决方案3】:

      使用受保护的:

      class BaseClass
      {
          protected SomeType MyThing;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-19
        • 2018-03-31
        • 2018-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多