2013-04-09 168 views
0

我目前有以下代碼模式,我在一般類MyClass的構造函數中初始化MyThing類型的特定對象。但是,在某些特定的派生類例子中(例如MySpecialClass),我想使用MyThing的派生版本,我稱之爲MySpecialThing。在基類構造函數中構造對象?

public class MyClass 
{ 
    public MyClass() 
    { 
     this.MyThing = new MyThing(); 
    } 

    public MyThing MyThing { get; set; } 
} 

public class MySpecialClass : MyClass 
{ 
    public MySpecialClass() 
    { 
     this.MyThing = new MySpecialThing(); 
    } 
} 

我的問題是,這是否是不好的做法,因爲效果MyThing屬性被在派生類中初始化兩次,一次是在基類和一次。很顯然,我可以傳遞一個布爾基類的構造函數或東西來告訴它不要打擾初始化MyThing,但可能是矯枉過正...

回答

5

這取決於有多少開銷有創造MyThing。

然而,有一個解決方案:

您可以添加一個受保護的基類構造函數接受類型MyThing的參數,並初始化它。

public class MyClass 
{ 
    private readonly MyThing myThing; 

    public MyClass(): this(new MyThing()) 
    { 
    } 

    protected MyClass(MyThing thing) 
    { 
     Contract.Requires(thing != null); 
     myThing = thing; 
    } 

    public MyThing MyThing { get { return myThing; } } 
} 

public class MySpecialClass : MyClass 
{ 
    public MySpecialClass(): base(new MySpecialThing()) 
    { 
    } 
} 

我認爲這比向公共基類構造函數中添加bool更好。

我也認爲這是值得的,即使構建MyThing的開銷很小,因爲它更清楚地表達了設計。

我也稍微改變了設計,使myThing成爲只讀字段,以表達它應該只在施工時設置的意圖。 (如果情況並非如此,並且您希望稍後設置,則必須恢復爲公共財產設置工具。)

+3

您甚至可以委託基類中的默認構造函數:public MyClass():this(new MyThing() ){}',但這只是一個意見問題:)總體而言,+1。 – 2013-04-09 10:01:53

+0

好點,我會調整代碼。 – 2013-04-09 10:02:59

+0

很好的答案,謝謝。關於使其只讀的好主意。我通常是隻讀變量的粉絲,它只是令人討厭,沒有類似於{get;組; }表示只讀屬性和字段的表示法。 – 2013-04-09 10:14:02

0

使用保護:

class BaseClass 
{ 
    protected SomeType MyThing; 
} 
1

您是否關注性能或可維護性?

性能問題只有在構造函數昂貴時纔有意義,或者您必須在緊密循環中創建大量對象。

我會更擔心可維護性,因爲您有多個地方初始化對象狀態。您可以將它傳遞給派生類的受保護的基類構造函數,並且默認使用MyThing默認構造函數