在C#与替代品中使用GetType/instanceof

use*_*279 6 c# oop reflection object instanceof

我在C#中制作的游戏中遇到了一个问题.这是一个简单的基于磁贴的匹配游戏,问题出现在我试图制造的电源上:

假设我们有基本的瓷砖类型,圆形正方形和菱形,它们都是瓷砖的子类.我试图将"匹配"行为提取到抽象的Tile方法,而不是让圈子只与圈子匹配:canMatchWith(Tile t).Tiles还有两种方法来添加/删除它们可以匹配的Tiles.

所以说我们在游戏中间有一个圆形瓷砖,我们有一个补充说"圆形瓷砖本回合可以与方形瓷砖匹配".我将浏览所有Circle图块并说出circleTile.addCanMatchWith(typeof(Square)).在内部,我们有一个List canMatchWith.

然后,我想说"圆圈不能再与正方形匹配",只需说circleTile.removeCanMatchWith(typeOf(Square)).

这是我目前的解决方案,并且它很好用,没有我注意到的性能缺陷(这是一个基于区块的匹配游戏,所以这些类型每个'移动'只评估一次,而不是逐帧评估).然而,我脑中的声音告诉我,这是完成这种行为的一种不好的方法.所以我有一些选择:

  1. 枚举...每个Tile可以由Tiletype类型变量组成.这将在构造函数中初始化,并设置为Type.SQUARE用于方块,依此类推.然后,每个Tile都有一个List canMatchWith,功能与我原来的实现相同.除了这种情况,它有点棘手.假设我有一些圆形子类,椭圆形和椭圆形.我希望椭圆能够与ONLY方格匹配,但是elipses可以匹配所有圆圈而不是正方形.

这里的问题是冗余,我的枚举现在也有OVAL和ELIPSE,并且Elipse类将具有(CIRCLE,OVAL,ELIPSE TileTypes)作为它可以匹配的类型.这完全是多余的,我想只说"Circle",我可以用类型.我想Tiles可以有TileType baseType和TileType actualType.

  1. 某种形式的行为构成.忘记Tile子类,只为Tiles方法和List的实例变量.然后,在运行时我们可以说someTile.addCanMatch(new CircleMatchBehavior()).这看起来很愚蠢,因为我会有一堆课程只是说你可以匹配一个特定的形状.

总之,我想要实现的是让多个对象类型能够与任意数量的不同类型进行交互.问题是,我应该为Type使用什么.可以在这里使用GetType吗?枚举?或者有人会推荐更好的策略吗?我试图尽可能通用,这些磁贴不应该在其他磁贴上有任何硬编码依赖,并且必须能够在运行时更改他们可以与之交互的人.假设我创建了一个新的Tile子类,五角形......好吧,Pentagons可以与Squares,Circles和Pentagons匹配.我的实现很简单,但有些东西告诉我这是一个肮脏的OOP练习.

我觉得我必须使用Types/Enums,因为我不是想说这个Tile.addCanMatch(Tile someOtherObject).这太具体了,我希望thisTile能够与作为特定类的实例的所有tile匹配.

Psy*_*unn 2

如果相似类型的所有形状总是共享一种行为,那么不将该行为存储在“每个实例”级别上是有意义的。相反,您可以拥有一个“CanMatchManager”,它存储按形状类型索引的列表字典。然后,当圆尝试比较匹配时,它会从 MatchManager 请求它可以匹配的类型。或者,MatchManager 可以接收这两个形状,并确定它们是否匹配。这就是中介者模式