DerivedClass作为ParentClass类型变量的值

时间:2018-08-14 02:07:51

标签: c# inheritance types type-conversion

我是C#的新手,我正在开发一个rpg游戏引擎。

我有我的基类Item,它是WeaponArmour的父类, 武器和盔甲类具有用于统计信息,武器插槽,盔甲类型等的额外变量。

我的Player班:

class Player{
    Armour helmet;
    Armour chest;
    Weapon mainHand;
    Item offHand;

这是我将物品装备到其相应插槽中的方法(固定方法)

    void equipItem(Item pz)
    {
        switch (pz)
        {
            case Weapon w when (w.weaponType == WeaponType.OneHandWeapon):
                mainHand = pz; // Cannot convert-to-Type Error *
                break;
            case Weapon w2 when (w2.weaponType == WeaponType.TwoHandWeapon):
                mainHand = pz; // **
                toInventory(offHand);
                offHand = null;
            case Armour a when (a.armourType == ArmourType.Chest):
                chest = pz; // **
                break;
            case Armour a when (a.armourType == ArmourType.Helmet):
                helmet = pz; // **
                break;
            default:
                break;
        }
    }
    void equipOffhand(Item pz)
    {
        if (mainHand.weaponType != WeaponType.TwoHandWeapon)
        {
            offHand = pz;
        }
        else
        {
            //error cannot equip off hand while wielding 2handWeapon
        }
    }

非常简单的模型。

我想要实现的是

var ss = new Weapon()
{
    weaponType= WeaponType.oneHandedWeapon,
};
equipItem(ss);
equipOffHand(ss);

但是如何摆脱类型转换错误呢?

2 个答案:

答案 0 :(得分:3)

采用适当的面向对象设计,您无需枚举即可告诉您某项属于什么位置,也不需要切换案例语句来触发正确的项-code smell

选择插槽是一种行为。您继承并覆盖的行为以及多态性会通过记住对象的类型来照顾其余的行为。这种方法不仅为您提供了更多的结构化代码,而且还将执行得更好(更少的CPU,更好的分支预测等)。

这是一个简单的示例,应满足您的大部分要求:

abstract class Item
{
    public abstract void Equip(Player player);
}

abstract class Armour : Item
{
}

class ChestPlate : Armour
{
    public override void Equip(Player player)
    {
        player.Chest = this;
    }
}

class Helm : Armour
{
    public override void Equip(Player player)
    {
        player.Helmet = this;
    }
}

class Weapon : Item
{
    public override void Equip(Player player)
    {
        player.MainHand = this;
    }
}

class OneHandedWeapon : Weapon
{
}

class TwoHandedWeapon : Weapon
{
    public override void Equip(Player player)
    {
        player.Offhand = player.MainHand = this;
    }
}

class Player
{
    public Armour Helmet { get; set; }
    public Armour Chest { get; set; }
    public Weapon MainHand { get; set; }
    public Item Offhand { get; set; }
}

现在,如果您想装备一件物品,只需执行以下操作:

item.Equip(player);

这里有一个link to a working example on DotNetFiddle,展示了更多的工作原理。

答案 1 :(得分:2)

我看到您正在使用新的模式匹配switch语句。例如,这种情况仅在物品的类型为Weapon并且是单手武器时才会运行:

case Weapon w when (w.weaponType == WeaponType.OneHandWeapon):

在这种情况下,pz将被“广播”到Weapon并存储在w中。因此,您可以使用w作为武器来指代该物品:

switch (pz)
{
    case Weapon w when (w.weaponType == WeaponType.OneHandWeapon):
        mainHand = w
        break;
    case Weapon w2 when (w2.weaponType == WeaponType.TwoHandWeapon):
        mainHand = w2
        toInventory(offHand);
        offHand = null;
    case Armour a when (a.armourType == ArmourType.Chest):
        chest = a;
        break;
    case Armour a when (a.armourType == ArmourType.Helmet):
        helmet = a;
        break;
    default:
        break;
}