2012-02-26 63 views
15

我正在開發一個涉及大量接口和繼承的項目,這些項目開始變得有點棘手,現在我遇到了一個問題。在基礎構造函數中使用'this'?

我有一個抽象類State,它接受一個Game對象作爲構造函數參數。在我的Game類的構造函數中,它需要一個狀態。這個想法是,當從抽象基類Game類繼承時,在調用基類的構造函數時,給它一個初始狀態對象。然而,這個狀態對象需要與您創建它相同的遊戲。代碼如下所示:代碼如下所示:

public class PushGame : ManiaGame 
{ 
    public PushGame() : 
      base(GamePlatform.Windows, new PlayState(this), 60) 
    { 
    } 
} 

但是,這不起作用。我只能假設因爲'this'關鍵字在構造函數開始執行之後纔可用。嘗試在基類的構造函數中使用它顯然不起作用。那麼,對此我最好的解決方法是什麼?我的計劃B是從Game類的構造函數中刪除State參數,然後在構造函數代碼中設置狀態。

有沒有一種更簡單,干擾較小的方式來做到這一點?

+1

請不要用「C#」等標題來標題。這就是標籤的用途。 – 2012-02-26 06:55:45

回答

9

顯然ManiaGame類總是使用PlayState類型的對象,這樣你就可以在ManiaGame水平移動創作:

public class PushGame : ManiaGame 
{ 
    public PushGame() : base() 
    { 
    } 

} 

public class ManiaGame 
{ 
    PlayState ps; 
    public ManiaGame() { 
     ps = new PlayState(this); 
    } 
} 

如果你想更具體的PlayState類..

public class PushGame : ManiaGame 
{ 
    public PushGame() : base() 
    { 
    } 
    protected override PlayState CreatePlayState() 
    { 
     return new PushGamePlayState(this); 
    } 
} 

public class ManiaGame 
{ 
    PlayState ps; 
    public ManiaGame() { 
      ps = CreatePlayState(); 
    } 
    protected virtual PlayState CreatePlayState() 
    { 
     return new PlayState(this); 
    } 
} 

public class PlayState 
{ 
    public PlayState(ManiaGame mg) {} 
} 


public class PushGamePlayState : PlayState 
{ 
    public PushGamePlayState(ManiaGame mg) : base(mg){} 
} 
+0

+1,它還突出了ManiaGame和PlayState之間的相互依賴關係,因此這兩個對象不能在相應的構造函數中「同時」交叉引用。 – StuartLC 2012-02-26 07:04:21

+1

重要的是要提到從ctor內部調用虛擬方法可能會很危險 - http://stackoverflow.com/questions/119506/virtual-member-call-in-a-constructor – AlexD 2012-02-26 12:45:01

0

看起來'this'只能用於在該上下文中引用另一個構造函數。

也就是說,構造函數執行之前,這是作爲一個範圍關鍵字:

: this("ParameterForAnotherConstructor") 

但它不能作爲它通常提到的類的實例,

: base(this) // Keyword this is not available in this context 

而且很明顯它不能調用任何實例方法要麼

: base(GetThis()) // Object reference is required 

有一個類似的堆棧溢出曲Keyword 'this' (Me) is not available calling the base constructor解決方法類似於您的建議。

1

如果所使用的State實現取決於具體的Game類,然後我會在子類Game類(PushGame)的構造函數內創建State的新實例,並通過abstract屬性訪問基類中的State

public class PushGame : ManiaGame 
{ 
    private readonly PlayState gamePlayState; 

    public PushGame() : base() 
    { 
     gamePlayState = new PlayState(this); 
    } 

    protected override State GamePlayState 
    { 
     get { return gamePlayState; } 
    } 
} 

public abstract class ManiaGame 
{ 
    protected abstract State GamePlayState { get; } 
} 

public class State 
{ 
    public State(ManiaGame mg) { } 
} 


public class PlayState : State 
{ 
    public PlayState(ManiaGame mg) : base(mg) { } 
} 
0

您的設計是否區分遊戲(如步步高)和正在進行的遊戲(一個西洋雙陸棋遊戲)?如果你想混合這兩個概念,那麼我會建議分別建模它們。例如,步步高和BackgammonContest。

相關問題