如何在一个变量中处理多个枚举类型

时间:2014-02-23 09:19:44

标签: c#

我不知道这是否可能,但我正在编写一个使用XNA和C#的简单游戏,并且不知何故需要一个特定的变量才能处理多个枚举类型。您控制的角色有一个库存槽,可以是以下水果类型之一:

public enum Fruit : int {Apple, Banana, Orange};
public Fruit carrying;

但角色也可以携带其他东西:

public enum Misc : int {Parcel, Brush};

我不想将它们全部合并到一个枚举中,因为我希望Fruit枚举是独特的,我不希望有两个不同的'携带'变量 - 一个用于Fruit,一个用于Misc。

有没有任何方法可以使用超级枚举,可以将它们合并为所有五个成员的第三个枚举?

编辑:感谢您的回复。我决定创建一个Item类型(其成员是一个区分Fruit和Misc的枚举)并通过XML将它们加载到List中。

2 个答案:

答案 0 :(得分:7)

听起来你可能想要CarriableItem或类似的联合类型。例如:

public sealed class CarriableItem
{
    public Fruit? Fruit { get; private set; }
    public Misc? Misc { get; private set; }

    // Only instantiated through factory methods
    private CarriableItem() {}

    public static CarriableItem FromFruit(Fruit fruit)
    {
        return new CarriableItem { Fruit = fruit };
    }

    public static CarriableItem FromMisc(Misc misc)
    {
        return new CarriableItem { Misc = misc };
    }
}

您可能然后想要另一个枚举来指示正在携带哪种项目:

public enum CarriableItemType
{
    Fruit,
    Misc
}

然后将属性添加到CarriableItem

public CarriableItemType { get; private set; }

并在工厂方法中正确设置。

然后你的人只有一个CarriableItem类型的变量。

答案 1 :(得分:0)

为什么要限制自己的枚举?如果您有一个界面及其各种实现,您可以自定义项目的行为!

// generic item. It has a description and can be traded
public interface IItem {
    string Description { get; }
    float Cost { get; }
}

// potions, fruits etc., they have effects such as
// +10 health, -5 fatigue and so on
public interface IConsumableItem: IItem {
    void ApplyEffect(Character p);
}

// tools like hammers, sticks, swords ect., they can
// be used on anything the player clicks on
public interface IToolItem: IItem {
    void Use(Entity e);
}    

这将使您的代码比使用枚举区分不同项目更容易,更有条理。如果您仍然需要这样做,则可以利用is运算符和方法IEnumerable.OfType。所以这就是你能做的:

public class HealthPotion: IConsumableItem {
    public string Description {
        get { return "An apple you picked from a tree. It makes you feel better."; }
    }

    public float Cost {
        get { return 5f; }
    }

    public void ApplyEffect(Character p) {
        p.Health += 1;
    }
}

public class Player: Character {
    public List<IItem> Inventory { get; private set; }

    private IEnumerable<IConsumableItem> _consumables {
        get { return this.Inventory.OfType<IConsumableItem>(); }
    }

    public void InventoryItemSelected(IItem i) {
        if(IItem is IConsumableItem) {
            (IItem as IConsumableItem).ApplyEffect(this);
        }
        else if(IItem is IToolItem) {
            // ask the player to click on something
        }
        else if /* ...... */

        this.Inventory.Remove(i);
    }
}