![](/img/trans.png)
[英]How to avoid duplication of code when using two constructors in a class C#
[英]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.