在 C# 中处理指定的成员类

发布于 2024-12-06 02:39:21 字数 664 浏览 5 评论 0原文

在构建类结构时,我希望派生类可能拥有派生成员类。例如:

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

这虽然过于简单化,但却表达了实际意义。现在假设存在事件等,我想在基类构造函数中附加公共事件,在派生构造函数中附加专用事件。例如,西洋跳棋和西洋棋棋子都可能有“捕获”事件和“移动”事件。我想将它们附加到基本构造函数中。但是,特定的事件(例如“castled”或类似的事件)将仅附加在特定的构造函数中。

我遇到的问题是基本构造函数似乎只能在派生构造函数之前运行。我如何实现这一点,以便在调用基本“游戏”构造函数以附加到事件之前实际实例化“游戏件”。

我的直觉表明,最好通过从构造函数中删除该功能并简单地使用“Attach()”成员函数并在那里处理它来更好地处理它。但是,我想确保我朝着正确的方向前进,因为似乎应该有一种方法可以在构造函数中做到这一点。

In 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

疾风者 2024-12-13 02:39:21

您可以尝试将其从子级注入到父级,如下所示:

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 的任何地方使用工厂对象来解决。


编辑:我实际上意识到我发布的原始代码示例不正确;无法在 Checkers 类中引用 Checker 片段(作为 Checker)。但是,如果您也将 Checker 片段注入其中,问题就解决了,并且您有了参考。顺便说一下,这是依赖注入

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.

傲世九天 2024-12-13 02:39:21

您可以尝试模板设计模式:

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

现在您可以在 Game Init 方法中插入通用事件处理,并在后代中使用具体处理逻辑覆盖它。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文