开发者

Handling Specified Member Classes In C#

开发者 https://www.devze.com 2023-04-05 23:24 出处:网络
开发者_StackOverflowIn building a class structure, I would like to have derived classes potentially posses derived member classes. For example:

开发者_StackOverflowIn building a class structure, I would like to have derived classes potentially posses derived member classes. For example:

class GamePiece
{ 
}
class Checker : GamePiece
{}
class ChessMan : GamePiece
{}

class Game 
{
   protected GamePiece _piece;
}

class Checkers : Game
{
   Checkers(){ _piece = new Checker(); }
}
class Chess : Game
{
   Chess(){_piece = new ChessMan();}
}

This is seriously oversimplified, but makes the actual point. Now assuming that there are events and such, I would like to attach the common ones in the base class constructor, and the specialized ones in the derived constructor. For example both a checker and a chessman might have a "captured" event and a "moved" event. I would like to attach them in the base constructor. However, events that would be specific such as "castled" or something like that would be attached only in the specific constructor.

The problem I have is that the base constructor seems to only be able to run BEFORE the derived constructor. How do I effect this such that I get to actually instantiate the "gamepiece" before I call the base "Game" constructor to attach to events.

My gut suggests that this is better handled by removing that functionality from the constructor and simply having an "Attach()" member function and handling it there. However, I want to make sure I am going in the right direction, since it would seem there should be a way to do it in the constructor.


You can try injecting it from child to parent, like this:

abstract class Game {
   protected GamePiece _piece;

   protected Game(GamePiece piece)
   {
       _piece = piece;
      // do the common work with pieces here
   }
}

class Checkers : Game 
{
   public Checkers(Checker piece) : base(piece)
   {
     // piece-specific work here
   }
}

If you need more complicated work done than just instantiating, you could create a static factory method that did all the work, and just call that when invoking the base constructor. This does change your Game implementation slightly in ways that change how you instantiate it, but that can be solved by using a factory object anywhere you need a new Game.


Edit: I actually realized the original code-sample I posted wasn't correct; there was no way to reference the Checker piece (as a Checker) in the Checkers class. But if you inject the Checker piece into that as well, the problem is solved and you have your reference. This is dependency injection, by the way.


You could try the Template design pattern:

class Game
{
    Game() { Init(); }
    protected virtual void Init() {}
}

Now you can insert generic event handling in the Game Init method and override it with concrete handling logic in the descendants.

0

精彩评论

暂无评论...
验证码 换一张
取 消