2012-02-26 11 views
15

Pracuję nad projektem, który wymaga wielu interfejsów i dziedziczenia, które zaczynają być trochę trudne, a teraz mam problem.Używanie "this" w konstruktorze podstawowym?

Mam stan klasy abstrakcyjnej, który przyjmuje obiekt Game jako argument konstruktora. W moim konstruktorze klasy Game zajmuje Stan. Chodzi o to, że dziedzicząc po abstrakcyjnej podstawowej klasie Game, wywołując konstruktor klasy podstawowej, nadajemy mu początkowy obiekt stanu. Jednak ten obiekt stanu przyjmuje tę samą grę, w której jest tworzony. Kod wygląda następująco:

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

To jednak nie działa. Mogę tylko założyć, że słowo kluczowe "this" nie może być użyte, dopóki konstruktor nie zacznie wykonywać. Próba użycia go w konstruktorze klasy podstawowej najwyraźniej nie działa. Więc jaki byłby mój najlepszy sposób obejścia tego? Mój plan B polega na usunięciu argumentu State z konstruktora klasy Game i po prostu ustawieniu stanu wewnątrz kodu konstruktora.

Czy jest to łatwiejszy, mniej inwazyjny sposób na zrobienie tego?

+1

Proszę nie zamieniać tytułów na "C#" i tym podobne. Po to są te tagi. –

Odpowiedz

9

Oczywiście klasa ManiaGame zawsze używa obiektów typu PlayState, więc można przejść do tworzenia na poziomie ManiaGame:

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

} 

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

Jeśli chcesz bardziej konkretnych klas 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, a także podświetla współzależność między ManiaGame i PlayState, więc 2 obiekty nie mogą nigdy zostać przekierowane "jednocześnie" w odpowiednich konstruktorach. – StuartLC

+1

Należy wspomnieć, że wywoływanie wirtualnej metody od wewnątrz ctor może być niebezpieczne - http://stackoverflow.com/questions/119506/virtual-member-call-in-a-constructor – AlexD

0

Wygląda na to, że "ten" może być użyty tylko do odniesienia do innego konstruktora w tym kontekście.

Oznacza to, że jest on używany jako słowo kluczowe określania zakresu zanim konstruktor wykonuje:

: this("ParameterForAnotherConstructor") 

Ale to nie jest dostępne jako zwykłe odniesienie do instancji klasy,

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

I oczywiście go nie można wywoływać żadnych metod instancji, ani nie ma żadnej metody instancji, która jest podobna do Stack Overflow qu estion, Keyword 'this' (Me) is not available calling the base constructor z obejściem podobnym do Twojej sugestii.

1

Jeśli zastosowana implementacja State zależy od konkretnej klasy Game, a następnie utworzę nową instancję klasy State wewnątrz konstruktora klasy potomnej Game (PushGame) i uzyskaj dostęp do State w klasie bazowej za pośrednictwem właściwości abstract.

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

Czy Twój projekt odróżnia grę (np. Backgammon) od gry w toku (gra w backgammon)? Jeśli próbujesz połączyć te dwie koncepcje, sugerowałbym ich osobne modelowanie. Na przykład Backgammon i BackgammonContest.

Powiązane problemy