.NET中的链接构造函数

时间:2016-08-26 12:36:00

标签: c# .net oop inheritance constructor

我尝试通过尽可能多地重用构造函数来保存代码并降低可维护性的失败率。现在,我遇到了一个情况,我认为我必须重复代码,但也许你知道一个解决方案。

public class Bar {
  public List<string> BarList {
    get;
    private set;
  }

  public Bar() {
    this.BarList = new List<string>();
  }

  public Bar(XmlNode node)
    : this() {
    //create from xml
  }
}

public class Foo: Bar {
  public List<int> FooList {
    get;
    private set;
  }
  public Foo()
    : base() {
    this.FooList = new List<int>();
  }

  public Foo(XmlNode node)
    : base(node) {
    //create from enhanced xml
  }
}

每个使用XMLNode作为参数的构造函数在初始化之前调用无参数构造函数。但是如何管理,派生类Foo调用自己的无参数构造函数和构造函数与基类的XmlNode参数?

构造函数链的期望行为是:

Foo(XmlNode)->Bar(XmlNode)->Foo()->Bar()

4 个答案:

答案 0 :(得分:2)

为什么不抽象构造函数的工作? 类似于:[检查新函数init]

public class Foo : Bar
{
    public List<int> FooList
    {
        get;
        private set;
    }
    public Foo()
      : base()
    {
        Init();
    }

    private void Init() { this.FooList = new List<int>(); }

    public Foo(XmlNode node)
      : base(node)
    {
        Init();
        //create from enhanced xml
    }
}

答案 1 :(得分:1)

如果我正确理解了您的问题,您希望Foo(XmlNode node)拨打this()base(node),这是无法完成的。

btw:ctor() : base()或您的情况Foo() : base()是隐含的。

这里唯一的选择是一些代码冗余。

E.g:

public class Foo: Bar {
    public List<int> FooList { get; private set; }

    public Foo() : base() {
        Initialize();
    }

    public Foo(XmlNode node) : base(node) {
        Initialize();
    }

    protected void Initialize() {
        this.FooList = new List<int>();
    }
}

答案 2 :(得分:1)

正如其他人已经回答的那样,除非您将行为抽象为单独的方法,否则您无法实现的目标。

但是,如果您想坚持使用构造函数,则另一种方法是使用可选参数,如下所示:

public class Bar {
  public List<string> BarList {
    get;
    private set;
  }

  public Bar(string xmlNode = null) {
    this.BarList = new List<string>();

    if (xmlNode != null) { 
        //create from xml 
    }
  }
}

public class Foo: Bar {
  public List<int> FooList {
    get;
    private set;
  }
  public Foo(string xmlNode = null)
  : base(xmlNode)
  {
    this.FooList = new List<int>();

    if (xmlNode != null) { 
        //create from enhanced xml 
    }
  }
}

当然,这里的妥协现在你在构造函数中有分支逻辑。

答案 3 :(得分:0)

这就是原因,为什么我总是反过来链接构造函数(无参数调用ctor有一个参数,调用ctor有两个参数,等等)。每个构造函数的目的只是为缺少的参数提供默认值,并且其主体保持为空。然后,所有工作都将在最专业的构造函数中完成,该构造函数调用基类的最专业的构造函数。这样,您始终只需要维护一个实现。

public abstract class Bar
{
    public List<string> BarList { get; private set; }

    public Bar()
        : this(null)
    { }

    public Bar(XmlNode node)
    {
        this.BarList = new List<string>();

        if (node == null)
            return;

        //create from xml
    }
}

public class Foo : Bar
{
    public List<int> FooList { get; private set; }

    public Foo()
        : this(null)
    { }

    public Foo(XmlNode node)
        : base(node)
    {
        this.FooList = new List<int>();

        if (node == null)
            return;

        //create from enhanced xml
    }
}