【发布时间】:2017-04-21 16:34:18
【问题描述】:
我对我正在编写的代码有一些疑问,希望您能启发我或帮助我找到更好的解决方案。
我有一个 Player 类,其中包含一些 Slot 类型的成员。每个 Slot(下面的代码)都包含一个 Equippable,它是一个由特定类(如 Armor、Weapon、Shield、MagicItem)实现的接口。我需要这样做,因为我不想为每种类型的可装备项目编写 Slot 类。
class Slot{
private Equippable item;
public Equippable Item = > item;
// here is constructor with default null item
// here are some methods to occupy/free slot
}
现在让我们回到 Player 类,我在其中有一些插槽:武器插槽、盔甲插槽等。这里我需要检索有关项目的信息;例如,我需要取回护甲加成。我需要做这样的事情:
int armorBonus = armorSlot.Item.Bonus;
显然这不起作用,因为 Slot 类型中的 Item 只是一个 Equippable 并且不一定具有 Bonus 属性。所以我想到了两种解决方案:
- 为 Equippable 提供 Bonus 属性:我可以在 Equippable 中放置一个 Bonus 属性,该属性将由每个类实现。这样,一切都会好起来的。 虽然,我觉得这并不完全正确,因为并非所有物品都需要奖金。我将如何处理具有不需要它的项目类型的 Bonus 属性?将其保留为默认值? 这是不是很笨拙?
- 执行强制转换:我可以通过以下显式转换来解决这种情况,但我不太习惯强制转换,所以我不确定我是否忽略了某些东西。这是继续的好方法吗?
代码如下:
Armor armor = (Armor)armorSlot.Item;
int armorBonus = armor.Bonus;
困扰我的是,我应该小心为每个插槽提供正确的项目类型(直到运行时异常我才知道),因为插槽不知道它允许包含什么类型的 Equippable。
好吧,我在写的时候想到了另一个想法,所以我把它放在这里:
- 告诉 Slot 它可以容纳哪个物品:这更像是对第二个解决方案的改进,而不是一个新的解决方案。我可以在 Slot 中存储一个字符串(甚至是一个枚举),告诉它它可以接受哪个项目,所以我确信我正在做正确的转换。不过,我如何检查它是否收到了正确类型的项目? 此外,我认为我应该无论如何这样做,以避免将项目分配到错误的插槽。
您对如何改进这一点有任何想法吗?
【问题讨论】:
-
您可以编写第二个支持 Bonus 属性的接口:
IHasBonus或其他。if (armorSlot.Item is IHasBonus) { ...。项目可以实现也可以不实现。 -
如果这个问题似乎在这个项目的许多相关形式中出现,你可以考虑编写一个属性包接口,一切都需要支持:
double bonus; if (armorSlot.Item.TryGetProperty(Props.Bonus, out bonus)) { ... -
C# 不允许多重继承,但它允许多个接口实现(以及接口分组):
public interface IEquippable { }、public interface IBonusProvider { },如果您仍需要将两者都作为接口操作,您可以使用 @ 987654329@ -
感谢双方,我会尝试这个解决方案。 @EdPlunkett:不过,我不明白你的第二条评论。
-
@Harnak 我的意思是,给他们某种内部属性字典,这样您就可以询问该项目的
Bonus属性,它要么给你价值,或者说它没有。现在你对Bonus有这个问题;也许会有其他六个属性。这是否意味着编写六个接口,或者可能是四个(如果其中一些属性一起使用)?如果你知道 WPF,也许最好写一个从对象中获取任意属性的通用方案,有点像 WPF 中的 DependencyObjects。
标签: c# interface casting subclass