-1

我有一个关于链接构造函数的问题我在 StackOverflow 和一些 c# 文章上阅读了一些问题,但我无法完全理解该主题。所以我有一个由 DerivedClass 继承的 BaseClass。在 DerivedClass 中,我没有参数构造函数,但它使用 base() 调用基本构造函数,并且它还传递了一个值。这是构造函数中使用的 base 关键字的主要目的,用于将值从派生类传递给继承的类,还是更多。而且在派生类中,我们还有第二个构造函数,它接受 1 个参数及其用法:this()。我不明白为什么当我删除时: this() 从这个构造函数“VS”告诉我“没有给定的参数对应于 BaseClass.BaseClass(int) 所需的形式参数“i”?为什么我不能

public class BaseClass
{
    protected int _Num;

    public BaseClass(int i)
    {
        _Num = i;
    }

    public int Num { get => this._Num ; set => _Num = value; }
}

public class DerivedClassA : BaseClass
{
    private string _Name;
    private int _AnotherValue;

    public string Name { get => this._Name ; set => this._Name = value; }
    public int AnotherValue { get => this._AnotherValue; set => this._AnotherValue = value; }

    public DerivedClassA() : base(123)
    {
        _Name = "testing";
    }

        public DerivedClassA(int param2) : this()      <-- Why i can't compile the program without the this() keyword here ?
        {
            AnotherValue = param2;
        }
    }

public class Program
{
        public static void Main(string[] args)
        {
            DerivedClassA objA = new DerivedClassA(5);
        }
}
4

1 回答 1

2

我找不到完全匹配的副本,所以我会提供一个答案。

想象一下这些类:

public class Base
{
    public Base()
    {
    }
}

public class Derived : Base
{
    public Derived()
    {
    }
}

在线尝试

初始化派生类时,必须先初始化基类。在我们上面的例子中,基类有一个无参数的构造函数,所以派生类可以隐式调用它。如果我们添加一个基本的第二个构造函数,这个逻辑仍然成立,并且仍然会隐式调用无参数构造函数:

public class Base
{
    public Base()
    {
    }

    public Base(int a)
    {
    }
}

public class Derived : Base
{
    public Derived()
    {
    }
}

在线尝试

但是如果我们去掉无参数构造函数,Derived 现在必须显式调用基构造函数:

public class Base
{       
    public Base(int a)
    {
    }
}

public class Derived : Base
{
    public Derived() : base(1)
    {
    }
}

在线尝试

那么如果我们添加一个额外的派生类构造函数会发生什么?好吧,这也必须调用基类(直接或间接):

public class Base
{       
    public Base(int a)
    {
        // this method body is executed first
    }
}

public class DerivedA : Base
{
    public DerivedA(string name, int val) : base(val)
    {
        // this method body is executed second (last if you used this constructor, e.g. new DerivedA("hello", 1) )
    }

    public DerivedA() : this("test", 5) // this will call the constructor above, which will first call base. So the final chain is: base, constructor above, this constructor
    {
        // this method body is executed third (last if you used this constructor, e.g. new DerivedA() )
    }
}

public class DerivedB : Base
{
    public DerivedB(string name, int val) : base(val)
    {
    }

    public DerivedB() : base(5) // this will call the base constructor, and then this constructor. The constructor above will not be used.
    {

    }
}

在线尝试

请注意,当没有定义其他构造函数时,所有类都有一个无参数构造函数,因此以下两个示例是等价的:

public class BaseA
{

}

public class BaseB
{
    public BaseB()
    {
    }
}

您会注意到SharpLab显示编译器从中删除了空构造函数,BaseB()因为它是多余的。

最后,没有显式定义构造函数的派生类仍会隐式调用基类构造函数:

public class Base
{       
    public Base()
    {
        // this method body is executed first
        Console.WriteLine("Base constructor");
    }
}

public class Derived : Base
{
}

在线尝试

总结一下:除非您的基类具有无参数构造函数,否则派生类构造函数必须直接调用基构造函数,或通过另一个派生类构造函数间接调用。显然,您只需要调用一个基本构造函数方法,就像任何其他类实例化一样。您不需要为每个基本方法匹配派生方法,只要您可以使用您拥有的值构造基本方法即可。

于 2019-06-26T05:05:01.003 回答