为什么不能在C#构造函数中同时使用:base()和:this()

时间:2014-09-02 23:16:10

标签: c#

我的类中有一个初始化东西的默认构造函数。

我不希望将其复制/粘贴到我需要的:base(otherStuff)的另一个构造函数中。我猜我必须(或将其抽象出方法或某些东西)。

但我想知道,为什么两者都不受支持?

(有时当我想要语言不支持的东西时,意味着我做错了。)

示例:

public class SomeClass : SomeBase
{
      public SomeClass()
      {
          // Init a lot of lists and stuff
      }

      public SomeClass(OtherThings otherThings): base(otherThings)
             // :this()  <----- This is not legal syntax
      {
          // Do stuff with otherThings
      }
}

4 个答案:

答案 0 :(得分:3)

我认为这样做的原因是,在执行类型的任何构造函数之前,基本构造函数始终执行,这意味着从现有构造函数{{1}派生你的类型已经嵌入了基础构造者c1() - 并且你显然不能从2个不同的基础构造中派生出来。

由于b1()构造函数实际上是从this()构造函数隐式派生的,所以有点令人困惑,所以你的代码相当于:

base()

现在很明显你不能拥有public class SomeClass : SomeBase { public SomeClass(): **base()** { // Init a lot of lists and stuff } public SomeClass(OtherThings otherThings): base(otherThings) // :this() <----- This is not legal syntax { // Do stuff with otherThings } } ,因为编译器无法执行2个基本构造函数(SomeClass(OtherThings otherThings): base(otherThings):this()base(otherThings))。


<强> UPD: 考虑到为什么禁止依赖2个构造函数,我进入了这个例子:

base()

允许public class SomeBase { public SomeBase(){} public SomeBase(OtherThings otherThings):this(){} } public class SomeClass : SomeBase { public SomeClass(): base() { // Init a lot of lists and stuff } public SomeClass(OtherThings otherThings): base(otherThings) // :this() <----- This is not legal syntax { // Do stuff with otherThings } } 会导致SomeClass(OtherThings otherThings):base(otherThings):this()被执行两次,这是荒谬和意外的(一次为SomeBase(),另一次为:base(otherThings),这两者都依赖于无参数构造函数SomeClass(): base())。

答案 1 :(得分:2)

我不确切知道为什么,但我过去有类似的东西,不得不求助于... ...

public class SomeClass : SomeBase
{
      public SomeClass()
      {
          // Init a lot of lists and stuff
          CommonStuff();
      }

      public SomeClass(OtherThings otherThings): base(otherThings)
      {
          CommonStuff();

          // Do stuff with otherThings
      }

      private void CommonStuff()
      {
         // init common between both
      }
}

答案 2 :(得分:2)

考虑这种情况:

class Base 
{
    public Base() { }
    public Base(string s) { }
}

class Derived : Base
{
    public Derived() : base("default") { }
    public Derived() : base()
                     : this() { }
}

应该很清楚,如果允许,这可以保证会造成麻烦。最终会调用哪个基础构造函数?

已经提供了解决方案:将其提取到方法中。

答案 3 :(得分:0)

这背后有一个非常可靠的推理 - 在开始在派生类型中构造构造函数之前,你的基类应该被完全初始化。

从您的示例看,您有两种不同的方法来初始化一个类 - 也许您应该考虑更改您的架构以便更简单?

如果不可能,您可能确实喜欢使用初始化方法或链接构造函数,如:

    class A
    {
        // no longer needed
        //public A()
        //{

        //}

        public A(SomeStuff stuff)
        {
            if (stuff != null)
            {
                // init stuff
            }
        }
    }

    class B : A
    {
        public B() : this(null)
        {

        }

        public B(SomeStuff stuff) : base(stuff)
        {
            if (stuff != null)
            {
                // init stuff more
            }
        }
    }

在这种情况下,您的施工链是正确的 - this.default() -> this.specialized(null) -> base.specialized(null)

当然,如果A()正在执行任何重要操作,您可以保留它,只需从A(SomeStuff)拨打电话。