C# 使属性在满足条件时可见

本文关键字:条件 满足 属性 | 更新日期: 2023-09-27 17:56:12

我终于开始研究OOP原理,目前正在制作一个简单的游戏。情况如下:我有一个名为 Items 的抽象类,它将项目的所有可能属性保存为属性,将项目的质量保存为枚举:

public enum ItemQuality
{
    Common,
    Uncommon,
    Rare,
    Epic,
    Legendary
}
public abstract class Items
{
    public ItemQuality ItemQuality { get; set; }
    public int Stamina { get; set; }
    public int Strength { get; set; }
    public int Agility { get; set; }
    public int Intelligence { get; set; }
    public int Damage { get; set; }
    public int Block { get; set; }
    public int Armor { get; set; }
}

我还有两个类,称为武器和盔甲(它们继承了物品类),它们分别持有武器类型和盔甲类型,两者都是枚举。

考虑以下场景:我制造了一把剑类型的新武器,我可以给它一个格挡值,但它是无法格挡的武器。我想根据武器/盔甲类型显示不同的属性。

Weapon weapon = new Weapon();
weapon.WeaponType = WeaponType.Sword;
weapon.Block = 5;

在这种情况下,我应该看不到 Block 属性。

更进一步,我不想将武器和盔甲与角色分开实例化(我还有一个角色类)。

我的最终目标是做这样的事情:

Character character = new Character();
character.WeaponType = WeaponType.Sword;
character.WeaponType.Damage = 10;

或者类似的东西,我什至不确定我的结构是否正确,所以我愿意接受建议!谢谢!

C# 使属性在满足条件时可见

在这里忘记继承并使用组合。例如,从基础开始:

公共枚举项质量{ 常见 罕见 罕见 史诗 传奇}

public class Item
{
    public ItemQuality ItemQuality { get; set; }
    // other things common to all items here
    public List<IFeature> features { get; set; }
}

那么IFeature是什么.首先,这是一个空接口:

public interface IFeature { }

但是现在让我们开始添加武器:

public interface IAttackWeapon : IFeature
{
    int Damage { get; set; }
}
public interface IDefenceWeapon : IFeature
{
    int Block { get; set; }
}

然后我们可以开始定义一些类:

public class Weapon : IAttackWeapon
{
    public Damage { get; set }
}
public class Shield : IDefenceWeapon
{
    public int Block { get; set; }
}

那么,我可以定义一些武器:

public static readonly Item ShortSword = new Item
{
    ItemQuality = ItemQuality.Common,
    Cost = 5,
    Features = new List<IFeature>
    {
        new Weapon { Damage = 4 }
    }
}

通过采用这种组合方法,如果我们说以后想要一把魔剑,我们不需要创建更多的类,更多的属性来隐藏等。我们也不会遇到"我的魔剑应该继承武器还是魔法物品"的问题。相反,我们会添加一个新功能,例如:

public static readonly Item MagicSword = new Item
{
    ItemQuality = ItemQuality.Rare,
    Cost = 5000,
    Features = new List<IFeature>
    {
        new Weapon { Damage = 10 },
        new MagicItem { Spell = Spells.TurnToFrog }
    }
}

我不会选择这种方式,特别是如果你想保持良好的 OOP。

为什么不使用接口,例如一个 IAttacckable 和 IBlockable。盾牌将仅实现IB

可锁定接口,剑可锁定和IB可锁定,枪仅可锁定

你会问武器物体是否可以阻止

   if (currentWeapon is IBlockable)
   {
        var blockWeapon = currentWeapon as IBlockable;
        blockWeapon.blockHorizontal();
        blockWeapon.blockVertical();
   }

根据 OOP 原则,将对象类型定义为枚举器是一个糟糕的设计。好的OOP将利用继承和可能的多态性。诸如此类:

public abstract class Weapon {
    public int cost {get; set;}
}
public class Sword : Weapon {
    public int damage {get; set;}
}
public class Shield : Weapon {
    public int defense {get; set;}
}

现在你可以说:

Sword blade = new Sword();
blade.cost = 5;
blade.damage = 6;
Shield myShield = new Shield();
myShield.cost = 4;
myShield.defense = 7;

如果你需要一种新型武器,你可以像我们对剑和盾所做的那样子类武器类(假设你想要弓)。例如,如果您需要其他攻击武器,如刀,则可以对剑进行子类。

public class Knife {
    public int length {get; set;}
}