何时使用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是否是一把剑,如果是,则将其转换为一把剑,然后装备它。但是有一些关于这让我认为我正在接近它不正确,当然,我可以只是添加一个虚拟方法的基类项目,但又一次,我不希望所有的项目都有可装备的选项。

对不起,如果我跑题了。

你怎么看,我处理得对吗?

何时使用as来投射对象

我想你是对的。

我同意你不想给Item添加一大堆不相关的东西。

我认为你可以想出一些广泛的接口来简化代码。

例如,您可以有一个IEquippable接口,它有一个Equip()方法。那么任何可装备的道具都将执行IEquippable

您可以使用其他接口以类似的方式表示其他事物,例如IConsumableIPortable

在你的代码中,你可以这样做:
IEquippable equippable = item as IEquippable;
if (equippable != null)
    equippable.Equip(); /// Etc

使用Linq你可以写这样的东西:

foreach (var equippableItem in inventoryItems.OfType<IEquippable>())
{
    equippableItem.Equip();
}

然而,您应该尽可能保持强类型集合——当然,库存本质上是一个异构集合。

还请注意,使用接口来表示这些概念允许你拥有实现多个概念的道具,例如IConsumableIPortable的药水。

把做这些的逻辑放到单独的类中隐藏起来可能是个好主意;例如,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.
}