2012-02-26 8 views
15

私は多少のインターフェースと継承を含むプロジェクトに取り組んでいますが、少し難しくなり始めていますが、今は問題に遭遇しました。ベースコンストラクタで 'this'を使用していますか?

私は、ゲームオブジェクトをコンストラクタ引数として取り込む抽象クラスStateを持っています。私のGameクラスのコンストラクタでは、状態を取ります。基本クラスのコンストラクタを呼び出すとき、抽象基本Gameクラスから継承するとき、それに初期状態オブジェクトを与えるという考えがあります。しかし、この状態のオブジェクトは、あなたがそれを作成している同じゲームにかかるコードは次のようになります。

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

しかし、これは動作しません。コンストラクタが実行されるまで、 'this'キーワードは使用できないので、私は推測できます。あなたの基底クラスのコンストラクタでそれを使用しようとすると、明らかに動作しません。では、このための最善の回避策は何ですか?私の計画Bは、GameクラスのコンストラクタからState引数を削除し、その後コンストラクタコード内の状態を設定するだけです。

これを行うのが簡単で、邪魔にならない方法はありますか?

+1

タイトルに「C#」などのプレフィックスを付けないでください。それがタグのためのものです。 –

答えて

9

あなたはManiaGameレベルでの作成を動かすことができるように明らかにManiaGameクラスは常に、PlayStateタイプのオブジェクトを使用しています。

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との間の相互依存性も強調しているので、2つのオブジェクトをそれぞれのコンストラクタで「同時に」相互参照することはできません。 – StuartLC

+1

ctorの中から仮想メソッドを呼び出すことは危険です - http://stackoverflow.com/questions/119506/virtual-member-call-in-a-constructor – AlexD

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クラスに依存していますが、クラス(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

デザインは、ゲーム(バックギャモンと言う)と進行中のゲーム(バックギャモンのゲーム)の間で区別されますか?これらの2つのコンセプトを混在させようとしている場合は、別々にモデル化することをお勧めします。たとえば、BackgammonやBackgammonContestなどです。

関連する問題