Обработка указанных классов-членов в C # - PullRequest
2 голосов
/ 20 сентября 2011

При построении структуры классов я хотел бы, чтобы производные классы потенциально имели производные классы-члены.Например:

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();}
}

Это серьезно упрощено, но имеет смысл.Теперь, предполагая, что есть события и тому подобное, я хотел бы присоединить общие в конструкторе базового класса и специализированные в производном конструкторе.Например, у шахматиста и шахматиста может быть «захваченное» событие и «перемещенное» событие.Я хотел бы прикрепить их в базовом конструкторе.Тем не менее, события, которые будут специфическими, такими как «замкнутый» или что-то подобное, будут прикреплены только в конкретном конструкторе.

Проблема, с которой я столкнулся, заключается в том, что базовый конструктор, по-видимому, может запускаться только ДО производного конструктора.Как мне сделать это так, чтобы я мог на самом деле создать «игровой элемент», прежде чем вызвать базовый конструктор «Game» для прикрепления к событиям.

Мой инстинкт подсказывает, что это лучше обрабатывать, удаляя эту функциональность из конструктора и просто имея функцию-член Attach () и обрабатывая ее там.Тем не менее, я хочу убедиться, что я иду в правильном направлении, так как, казалось бы, должен быть способ сделать это в конструкторе.

Ответы [ 2 ]

3 голосов
/ 20 сентября 2011

Вы можете попробовать ввести его от ребенка к родителю, например:

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
   }
}

Если вам нужна более сложная работа, чем просто создание экземпляра, вы можете создать статический фабричный метод, который сделает всю работу, и просто вызвать его при вызове базового конструктора. Это немного меняет вашу реализацию Game способами, которые меняют способ ее создания, но это можно решить, используя фабричный объект везде, где вам нужен новый Game.


Редактировать: Я действительно понял, что исходный пример кода, который я разместил, был неправильным; не было никакого способа сослаться на элемент Checker (как Checker) в классе Checkers. Но если вы также добавите в него элемент Checker, проблема будет решена, и у вас будет ссылка. Кстати, это внедрение зависимостей .

2 голосов
/ 20 сентября 2011

Вы можете попробовать шаблон дизайна шаблона:

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

Теперь вы можете вставить общую обработку событий в метод Game Init и переопределить ее конкретной логикой обработки в потомках.

...