如果我有枚举
[Flags]
public enum GameFlow
{
Normal = 1,
NormalNoMove = 2,
Paused = 4,
Battle = 8
}
是否可以通过一次检查来检查枚举是否处于所需状态之一?例如,如果我想检查枚举是 Normal 还是 NormalNoMove,我是否总是必须这样写?
if(Flow == GameFlow.Normal || Flow == GameFlow.NormalNoMove)
如果只有两个值,这不是一个大问题,但会有更多的枚举状态,如果我只需在一处更改它那就太好了。如果枚举值是 Normal 或 NormalNoMove,是否可以创建一个返回 true 的枚举别名?或者我是否必须编写某种辅助方法来实现这一目标(扩展方法?)
也许有用
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))
模式匹配对于这样的逻辑来说读起来很好:
if(Flow is GameFlow.Normal or GameFlow.NormalNoMove)
像这样比较标志枚举的更传统方法是使用按位逻辑:
if((Flow & (GameFlow.Normal | GameFlow.NormalNoMove)) > 0)
也可以创建组合其他值的枚举值,正如我在here中提到的。
所以,就你而言:
[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 测试:
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
只是“延伸”Normal
。
根据 C# 9,我会使用模式匹配编写类似的表达式。在这种情况下。
if(Flow is GameFlow.Normal or GameFlow.NormalNoMove)
{
// your code...
}
根据对 @StringlingWarrior 答案的评论,您可以创建一个扩展方法来缩短代码:
public static class GameFlowExtensions
{
public static bool IsNormal(this GameFlow flow)
{
return (flow & (GameFlow.Normal | GameFlow.NormalNoMove)) > 0;
}
}
// usage:
if (Flow.IsNormal())
您可以将变量设置为等于
GameFlow.Normal
和 GameFlow.NormalNoMove
,然后将您拥有的值与它进行比较,如下所示:
GameFlow NormalOrNormalNoMove = GameFlow.Normal | GameFlow.NormalNoMove;
...
if ((Flow & NormalOrNormalNoMove) > 0)
{
// Your code
}
var requiredFlows = new [] {
GameFlow.NormalNoMove,
GameFlow.Normal,
// Other values of the GameFlow enum.
}.ToHashSet();
if (requiredFlows.Contains(currentFlow))
{
// Your code.
}
理想情况下,
requiredFlows
应该是 private static readonly
字段。