何时使用as来投射对象
本文关键字:对象 as 何时使 | 更新日期: 2023-09-27 18:15:24
我对我是否正确处理这个问题有点困惑。假设我有一款滚动玩法游戏,玩家可以在其中打败怪物并收集道具,以下是我的一些玩家类别: (c#)
public string Name { get; set; }
public double life { get; set; }
public double power { get; set; }
public Swords weapon { get; set; } // their Held weapon
private List<Items> items; //Represents their backpack
private Monster monster; //The monster they are currently facing.
public Player(string name)
{
this.Name = name;
life = 1000;
power = 10;
weapon = new Swords("Fists", 100, 1); //The power of the weapon. Can only punch at the start
items = new List<Items>();
}
public void addItem(Items i)
{
items.Add(i);
}
然后看看我的播放器类中的这个方法:
public void equiptSword() //
{
Swords tempSword;
foreach (Items i in items)
{
if (i is Swords)
{
tempSword = i as Swords;
tempSword.equiptItem(this);
}
}
}
正如你所看到的,我有一个名为items的超/基类,所有东西都是从它派生的。当玩家击败怪物时,他们将获得一把剑,我将其添加到道具列表中(他们的背包)。基类没有equiptItem()
的虚方法,只有剑类有这个方法。因此,我不能只输入类型items[5].equiptItem()
。这意味着我必须使用if语句来检查I是否是一把剑,如果是,则将其转换为一把剑,然后装备它。但是有一些关于这让我认为我正在接近它不正确,当然,我可以只是添加一个虚拟方法的基类项目,但又一次,我不希望所有的项目都有可装备的选项。
对不起,如果我跑题了。
你怎么看,我处理得对吗?
我想你是对的。
我同意你不想给Item
添加一大堆不相关的东西。
我认为你可以想出一些广泛的接口来简化代码。
例如,您可以有一个IEquippable
接口,它有一个Equip()
方法。那么任何可装备的道具都将执行IEquippable
。
您可以使用其他接口以类似的方式表示其他事物,例如IConsumable
和IPortable
。
IEquippable equippable = item as IEquippable;
if (equippable != null)
equippable.Equip(); /// Etc
使用Linq你可以写这样的东西:
foreach (var equippableItem in inventoryItems.OfType<IEquippable>())
{
equippableItem.Equip();
}
然而,您应该尽可能保持强类型集合——当然,库存本质上是一个异构集合。
还请注意,使用接口来表示这些概念允许你拥有实现多个概念的道具,例如IConsumable
和IPortable
的药水。
把做这些的逻辑放到单独的类中隐藏起来可能是个好主意;例如,Equipper
类处理装备的事情。
不过有一件事-我不明白为什么你必须通过穿过袋子来装备剑。我本以为你会有一组由怪物掉落的物品(我们称之为Loot
),你会像这样处理它们:
void handleLoot(Loot loot)
{
// Get first sword dropped, or null if none.
var sword = Loot.Items.OfType<Sword>().FirstOrDefault();
if (sword != null) // Sword implements IEquippable so we can:
sword.Equip(); // just equip it.
}