簡體   English   中英

調用不同的基本構造函數時如何避免構造函數之間的重復

[英]How to avoid duplication between constructors when they call different base constructors

我在 SO 上看到了這個問題的許多變體,但解決方案不適用於這種情況。

我有與此類似的代碼,但在Derived有冗長的構造函數,我想避免重復。

abstract class Base
{
    private int ID;

    protected Base( int id )
    {
        ID = id;
    }

    protected Base()
    {
        ID = GenerateID();
    }

    private int GenerateID()
    {
        return 42;
    }
}

class Derived : Base
{
    public readonly int SomeField;
    
    public Derived( int SomeFieldInitialValue ) : base()
    {
        SomeField = SomeFieldInitialValue;
    }

    public Derived( int SomeFieldInitialValue, int id ) : base( id )
    {
        // Want to remove this duplication - could be a long constructor.
        // Can't put it in a method because it does things that only constructors can do.
        SomeField = SomeFieldInitialValue;
    }
}

我無法在Derived創建一個輔助方法來包含所有構造函數通用的代碼,因為其中一些代碼只能在構造函數中完成(例如設置只讀成員)。

我不能只使用一個基本構造函數並傳遞默認值,因為用於Base.ID值只有Base知道(在私有GenerateID方法中計算)。

我不能使用字段初始值設定項,因為字段在每個構造函數中沒有被初始化為相同的東西,它們的值取決於構造函數參數。

在沒有要傳遞的 id 的情況下,我寧願不將Base.GenerateID公開給派生類來傳遞,因為沒有其他理由公開它,而且將基本功能推入派生類似乎很麻煩。 此外,未來可能還會有其他細節,而不僅僅是 int - 根據調用的Base構造函數,可能需要或不需要運行各種其他代碼 - 提供Derived知識似乎很糟糕。

我寧願避免從Derived成員中刪除readonly ,因為它們是故意readonly

我有一種感覺,答案將是“對不起,C# 不允許這樣做”,我必須在我不想采取的選項之一中進行選擇:) 我認為最不壞的選項是刪除readonly或可能用private set屬性替換這些字段。

如果您可以更改基類,那么最好只有一個構造函數。 這可以提供兩個選項(固定 ID 或新生成的 ID),如下所示:

abstract class Base
{
    private int ID;

    protected Base( int? id )
    {
        ID = id ?? GenerateID();
    }

    private int GenerateID()
    {
        return 42;
    }
}

同樣在派生類中,定義一個(私有或受保護的)構造函數來完成所有繁重的工作,然后公共構造函數重定向到這個。

class Derived : Base
{
    public readonly int SomeField;
    
    protected Derived( int SomeFieldInitialValue, int? id ) : base(id)
    {
        SomeField = SomeFieldInitialValue;
    }
    
    public Derived( int SomeFieldInitialValue ) : this( SomeFieldInitialValue, null)
    {
    }

    public Derived( int SomeFieldInitialValue, int id ) : this( SomeFieldInitialValue, id )
    {
    }
}

暫無
暫無

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

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