在枚举中明确定义标志组合

J M*_*Mor 14 c# enums flags state state-machine

我正在考虑实现一个定义游戏对象状态的枚举,我想知道我是否可以直接在枚举的定义中使用标志,而不是将对象的状态定义为标志的集合,没有简单的预定义,状态机中使用的状态的全局名称.

例如,假设有5种状态:PreActivation(创建但未开始;即未来波中的敌人),活动(当前正在使用;即屏幕上的敌人,攻击你),暂停(不再有效,但是可以重新激活;即如果玩家使用时间冻结的力量,则为敌人),DeActivated(已完成使用但仍在游戏世界中的物体;即死亡后身体遗留的敌人,如在毁灭战士1和2中),以及ToRemove(一个用于从游戏中删除的对象;即在你清除一个级别并移动到下一个级别后的敌人).

我想要做的是定义枚举,以便状态保存所有适用的标志; 例如,DeActivated敌人:1.先前已被激活,以及2.目前尚未激活.我目前的想法是做这样的事情:

public enum ObjectState
{
    // The first section are the flags
    BeenActivated   = 0b0000001, // Previously activated
    CurrentlyActive = 0b0000010, // Currently activated
    IsSuspended     = 0b0000100, // It may be reactivated
    ShouldRemove    = 0b0001000, // It should be removed
    // These are the states
    PreActivation   = 0b0000100, // Mot currently active, nor has it ever been active, but it will get activated
    Active          = 0b0000011, // Currently active,     and it's been active
    Paused          = 0b0000101, // Not currently active, but it's been active before
    DeActivated     = 0b0000001, // Not currently active, but it's been active before, and it shouldn't get reactivated, but don't remove yet
    ToRemove        = 0b0001001  // Not currently active, but it's been active before, and it shouldn't get reactivated, it should be removed
}
Run Code Online (Sandbox Code Playgroud)

据我所知,这应该可以正常工作,但我有几个主要问题:

  1. 这可能有什么问题吗?
  2. 这是不好的做法吗?
  3. 这是不好的做法吗?而且,如果是的话;
    • 答:它有什么问题?
    • B.我该怎么做?我只是让对象的状态成为这些标志的集合,但我想要一个特定状态的简写枚举,因为这允许特定实例的复杂性和需要时的简单性.有没有更可接受的方法来实现这一目标?

对不起,如果这是重复或我打破了其他规则,但我今天刚刚创建了一个帐户; 这是我的第一篇文章.另外,我不确定在搜索时你会称之为什么,我没有从这里或谷歌得到任何类似的点击.

Oli*_*bes 13

你可以这样做.这是旗帜枚举的重点.如果a enum旨在用作标志,请使用[Flags]属性标记它.

我建议将现有标志与按位或(|)相结合.它更易读,更不容易出错.

[Flags]
public enum ObjectState
{
    // Flags
    BeenActivated   = 0b0000001, // Previously activated
    CurrentlyActive = 0b0000010, // Currently activated
    IsSuspended     = 0b0000100, // It may be reactivated
    ShouldRemove    = 0b0001000, // It should be removed

    // States as combination of flags.
    PreActivationState   = IsSuspended,                     // Mot currently active, nor has it ever been active, but it will get activated
    ActiveState          = BeenActivated | CurrentlyActive, // Currently active,     and it's been active
    PausedState          = BeenActivated | IsSuspended,     // Not currently active, but it's been active before
    DeActivatedState     = BeenActivated,                   // Not currently active, but it's been active before, and it shouldn't get reactivated, but don't remove yet
    ToRemoveState        = BeenActivated | ShouldRemove     // Not currently active, but it's been active before, and it shouldn't get reactivated, it should be removed
}
Run Code Online (Sandbox Code Playgroud)

我还为各州添加了一个"状态"后缀,以便更好地将它们与旗帜区分开来.或者转过来并为标志添加"Flags"后缀.

  • 并且,它不仅更具可读性,而且如果您因任何原因将"BeenActivated"更改为"0b00000010",则无需在所有其他区域再次更改它 (2认同)