18

如果我有枚举

    [Flags]
    public enum GameFlow
    {
        Normal = 1,
        NormalNoMove = 2,
        Paused = 4,
        Battle = 8
    }

是否可以通过一次检查来检查枚举是否处于所需状态之一?例如,如果我想检查枚举是 Normal 还是 NormalNoMove,我总是必须这样写吗?

if(Flow == GameFlow.Normal || Flow == GameFlow.NormalNoMove)

如果只有两个值,这不是一个大问题,但是会有更多的枚举状态,如果我只需要在一个地方更改它会很好。如果枚举值是 Normal 或 NormalNoMove,是否可以创建一个返回 true 的枚举别名?还是我必须编写某种辅助方法来实现(扩展方法?)

4

6 回答 6

22

也许它会有用

public static class EnumExtensions
{
    public static bool IsOneOf(this Enum enumeration, params Enum[] enums)
    {
        return enums.Contains(enumeration);
    }
}

// usage:
if(Flow.IsOneOf(GameFlow.Normal, GameFlow.NormalNoMove))
于 2018-07-04T15:25:59.830 回答
17

按位逻辑应该适用于这样的标志枚举。

if((Flow & (GameFlow.Normal | GameFlow.NormalNoMove)) > 0)

正如我在这里提到的,还可以创建结合其他值的枚举值。

所以,在你的情况下:

[Flags]
public enum GameFlow
{
    Normal = 1,
    NormalNoMove = 2,
    Paused = 4,
    Battle = 8,
    AnyNormal = Normal | NormalNoMove
}

bool IsNormal(GameFlow flow)
{
    return (flow & GameFlow.AnyNormal) > 0;
}

和一个 LINQPad 测试:

void Main()
{
    IsNormal(GameFlow.Normal).Dump();// True
    IsNormal(GameFlow.NormalNoMove).Dump();// True
    IsNormal(GameFlow.Paused).Dump();// False
    IsNormal(GameFlow.Battle).Dump();// False

    IsNormal(GameFlow.Normal | GameFlow.Paused).Dump();// True
    IsNormal(GameFlow.NormalNoMove  | GameFlow.Battle).Dump();// True
    IsNormal(GameFlow.Paused | GameFlow.Battle).Dump();// False
    IsNormal(GameFlow.Battle | GameFlow.Normal).Dump();// True

}

根据您的评论,我想知道您是否也应该在这里修改按位标志。听起来“Normal”是您要检查的状态,“NormalNoMove”建立在此之上。也许你的枚举应该看起来更像这样:

[Flags]
public enum GameFlow
{
    Normal = 1,
    NormalNoMove = Normal | 2,
    Paused = 4,
    Battle = 8
}

这样,您可以检查是否flow & GameFlow.Normal > 0处于正常状态:NormalNoMove只是 "extends" Normal,可以这么说。

于 2013-08-01T18:04:57.700 回答
4

根据对@StringlingWarrior 的回答的评论,您可以创建一个扩展方法来缩短您的代码:

public static class GameFlowExtensions
{
    public static bool IsNormal(this GameFlow flow)
    {
        return (flow & (GameFlow.Normal | GameFlow.NormalNoMove)) > 0;
    }
}

// usage:
if (Flow.IsNormal()) 
于 2013-08-01T18:12:02.843 回答
3

根据 C# 9,我会使用模式匹配编写类似的表达式。在这种情况下。

if(Flow is GameFlow.Normal or GameFlow.NormalNoMove) 
{
   // your code...
}
于 2021-06-24T08:25:07.697 回答
1

您可以将变量设置为等于GameFlow.NormalGameFlow.NormalNoMove然后将您拥有的值与它进行比较,如下所示:

GameFlow NormalOrNormalNoMove = GameFlow.Normal | GameFlow.NormalNoMove;
...
if ((Flow & NormalOrNormalNoMove) > 0)
{
    // Your code
}
于 2013-08-01T18:14:16.943 回答
0
var requiredFlows = new [] {
    GameFlow.NormalNoMove,
    GameFlow.Normal,
    // Other values of the GameFlow enum.
}.ToHashSet();

if (requiredFlows.Contains(currentFlow))
{
    // Your code.
}

理想情况下,requiredFlows应该是一个private static readonly字段。

于 2022-01-06T14:41:47.520 回答