簡體   English   中英

在C#中調用重寫的構造方法和基本的構造方法

[英]Calling Overridden Constructor and Base Constructor in C#

我有兩個類Foo和Bar,它們具有如下構造函數:

class Foo
{
    Foo()
    {
      // do some stuff
    }

    Foo(int arg)
    {
      // do some other stuff
    }
}

class Bar : Foo
{
    Bar() : base()
    {
      // some third thing
    }
}

現在,我想為帶有int的Bar引入一個構造函數,但是我希望Bar()中發生的事情以及 Foo(int)中的事情都可以運行。 像這樣:

Bar(int arg) : Bar(), base(arg)
{
  // some fourth thing
}

在C#中有什么方法可以做到這一點? 到目前為止,我最好的方法是將Bar()完成的工作放到一個函數中,該函數也會被Bar(int)調用,但這非常不雅致。

我會重新鏈接構造函數,所以它們被稱為

Bar() : this(0) 
Bar(int) : Foo(int) initializes Bar
Foo(int) initializes Foo
Foo() : this(0) 

如果無參數構造函數為其他構造函數的int參數采用某種默認值,則這是合適的。 如果構造函數無關,則您的類型可能做錯了,或者我們需要有關您要實現的目標的更多信息。

不,這是不可能的。 如果使用Reflector檢查為每個構造函數生成的IL,您將明白原因-您最終將為基類調用兩個構造函數。 從理論上講,編譯器可以構造隱藏的方法來完成所需的操作,但是與您明確地執行相同操作相比,實際上並沒有任何優勢。

我建議您將構造函數鏈從最不特定的更改為最特定的。

class Foo
{
    Foo()
    {
      // do some stuff
    }

    Foo(int arg): this()
    {
      // do some other stuff
    }
}

class Bar : Foo
{
    Bar() : Bar(0)
    {
      // some third thing
    }

    Bar(int arg): base(arg)
    {
      // something
    }
}

現在,任何Bar對象的創建都將調用所有4個構造函數。 構造函數鏈接應該為更多特定的構造函數提供默認值,而不是相反。 您應該真正看一下您要完成的工作,並確保您所做的事情有意義。 Curt是正確的,出於技術原因,您不能執行此操作,但也有邏輯上的原因,您不應執行此操作。

這是我唯一能想到的...

 public class Foo
{
    public Foo()
    {
    }
    public Foo(int? arg): this()
    {
    }

}
public class Bar : Foo
{
    private int x;
    public Bar(): this(new int?()) // edited to fix type ambiguity
    {
        // stuff that only runs for paramerless ctor
    }
    public Bar(int? arg)
        : base(arg)
    {
        if (arg.HasValue)
        {
            // Do stuff for both parameterless and parameterized ctor
        }
        // Do other stuff for only parameterized ctor
    }
}

您不能擁有采用int調用無參數構造函數的Bar構造函數嗎?

您可以將Bar()中的內容放到Bar(int)中,並使用具有默認值的Bar()調用Bar(int)嗎? 然后Bar(int)可以調用基本構造函數。

class Bar : Foo
{
    Bar() : this(0)
    {
    }

    Bar(int arg) : base(arg)
    {
    }
}

那不能完全回答您的問題,但是根據您的情況,可能是一個可行的解決方案。

您能否將Bar()的初始化代碼用作方法並從兩個構造函數中調用它,並使新的構造函數僅調用base(arg)?

您可以使用以下代碼:

public Foo
{
    public Foo()
    {
        this.InitializeObject();
    }

    public Foo(int arg) : this()
    {
        // do something with Foo's arg
    }

    protected virtual void InitializeObject()
    {
        // initialize object Foo
    }
}

public Bar : Foo
{
    public Bar : base() { }

    public Bar(int arg) : base(arg)
    {
       // do something with Bar's arg
    }

    protected override void InitializeObject()
    {
       // initialize object Bar

       base.InitializeObject();
    }
}

就像上面的代碼一樣,只需重寫InitializeObject()方法,然后將要放入的所有代碼放入無參數構造函數中即可。 最后在代碼末尾調用base.InitializeObject()

希望這是有用的。

暫無
暫無

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

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