簡體   English   中英

構造函數中的Base()和This()。 (鏈式構造函數)

[英]Base() and This() in constructors. (Chained constructors)

我有一個關於鏈構造函數的問題,我在StackOverflow和一些C#文章中讀了一些問題,但是我不能完全理解該主題。 所以我有一個由DerivedClass繼承的BaseClass。 在DerivedClass中,我沒有參數構造函數,但是它使用以下方法調用基本構造函數:base(),並且還傳遞了一個值。 這是構造函數中用來將值傳遞給派生類的繼承類的基本關鍵字的主要目的,還是其他用途。 同樣在派生類中,我們還有另一個構造函數,該構造函數采用1個參數及其使用方式:this()。 我不明白為什么要刪除:為什么從這個構造函數“ VS”中的this()告訴我“沒有給定對應於BaseClass.BaseClass(int)的形式參數“ i”的參數?為什么我不能在DerivedClass中只有一個參數構造函數而不使用this()?

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);
        }
}

我找不到完全匹配的重復項,因此我將提供答案。

想象一下這些類:

public class Base
{
    public Base()
    {
    }
}

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

在線嘗試

初始化派生類時,必須首先初始化基類。 在上面的示例中,Base類具有無參數構造函數,因此派生類可以隱式調用它。 如果添加第二個基本構造函數,則此邏輯保持不變,並且無參數構造函數仍將隱式調用:

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
{
}

在線嘗試

總結一下:除非您的基類具有無參數構造函數,否則您的派生類構造函數必須直接調用基本構造函數,或通過另一個派生類構造函數間接調用。 顯然,與任何其他類實例化一樣,您只需要調用一個基本構造函數方法即可。 您不需要為每個基本方法匹配派生方法,只要您可以使用自己擁有的值構造基本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM