C# 确定是否在某个值上设置了任何标志
假设我有以下几点:C# 确定是否在某个值上设置了任何标志,c#,C#,假设我有以下几点: [Flags] public enum Options : long { None = 0, Flag1 = 0x00000001, Flag2 = 0x00000002, Flag3 = 0x00000004, Flag4 = 0x00000008, Flag5 = 0x00000010, // ... FlagV = 0x10000000000, FlagW = 0x20000000000,
[Flags]
public enum Options : long
{
None = 0,
Flag1 = 0x00000001,
Flag2 = 0x00000002,
Flag3 = 0x00000004,
Flag4 = 0x00000008,
Flag5 = 0x00000010,
// ...
FlagV = 0x10000000000,
FlagW = 0x20000000000,
FlagX = 0x40000000000,
FlagY = 0x80000000000,
FlagZ = 0x100000000000
}
目前,为了确定是否设置了标志,我正在执行以下操作:
(myOptions & (long)Options.Flag1) == (long)Options.Flag1
如何确定是否设置了FlagV上方的任何标志(例如FlagW、FlagX等)并检索其值(例如,如果设置了FlagW、FlagX和FlagZ,我想检索FlagW的值)?换言之,是否有替代方案:
if ((myOptions & (long)Options.FlagW) == (long)Options.FlagW)
return (long)Options.FlagW;
else if ((myOptions & (long)Options.FlagX) == (long)Options.FlagX)
return (long)Options.FlagX;
else if ((myOptions & (long)Options.FlagY) == (long)Options.FlagY)
return (long)Options.FlagY;
// etc.
您可以遍历所有选项值
var currentVal = Options.FlagV | Options.FlagW;
foreach (Options enumVal in Enum.GetValues(typeof(Options)))
if (enumVal > Options.FlagV && (enumVal & currentVal) == enumVal)
//Do stuff
您可以遍历所有选项值
var currentVal = Options.FlagV | Options.FlagW;
foreach (Options enumVal in Enum.GetValues(typeof(Options)))
if (enumVal > Options.FlagV && (enumVal & currentVal) == enumVal)
//Do stuff
这将为您提供在
myOptions
中设置的标志列表:
var flags = Enum.GetValues(typeof(Options))
.Where(f => myOptions.HasFlag(f))
.ToList();
编辑:看起来您的
myOptions
实际上是一个long,否则您的代码将无法编译,因为您无法将&
应用于枚举和long。因此,请尝试以下方法:
var enumVal = (Options)myOption;
var flags = Enum.GetValues(typeof(Options))
.Where(f => enumVal.HasFlag(f))
.ToList();
这将为您提供在
myOptions
中设置的标志列表:
var flags = Enum.GetValues(typeof(Options))
.Where(f => myOptions.HasFlag(f))
.ToList();
编辑:看起来您的
myOptions
实际上是一个long,否则您的代码将无法编译,因为您无法将&
应用于枚举和long。因此,请尝试以下方法:
var enumVal = (Options)myOption;
var flags = Enum.GetValues(typeof(Options))
.Where(f => enumVal.HasFlag(f))
.ToList();
首先,您可能需要重新考虑导致您使用超过32个标志的设计,因为这本身听起来很麻烦
除此之外,考虑到您只在执行位运算,所以如下所示的一些方法都是高效的(编译成一对夫妇指令),并且易于维护:
public enum Options : long
{
FlagA = 0x00000001,
// ...
FlagZ = 0x80000000,
// ...
HighFlags = 0xffff0000,
LowFlags = 0x0000ffff
}
然后,您可以通过执行(options&options.HighFlags)!=0
并使用选项和选项仅获取高标志
。高标志
如果无法修改枚举,或不想依赖特定值,也可以在运行时将这些值组合在一起:
public static class OptionsHelper
{
private readonly static Options HighFlags = Options.FlagM
| Options.FlagN
// ...
| Options.FlagZ;
public static bool HasHighFlags(this Options opt)
{
return (opt & HighFlags) != 0;
}
public static Options GetHighFlags(this Options opt)
{
return (opt & HighFlags);
}
public static IEnumerable<Options> GetSetHighFlags(this Options opt)
{
var highFlags = GetHighFlags(opt);
if (highFlags != 0)
{
for (ulong cFlag = 1; cFlag != 0; cFlag <<= 1)
{
if ((highFlags & cFlag) != 0)
{
yield return (Options)cFlag;
}
}
}
}
}
公共静态类选项帮助器
{
私有只读静态选项HighFlags=Options.FlagM
|选项.FlagN
// ...
|Options.FlagZ;
公共静态bool HasHighFlags(此选项可选)
{
返回(可选和高标志)!=0;
}
公共静态选项GetHighFlags(此选项可选)
{
返回(选择和高标记);
}
公共静态IEnumerable GetSetHighFlags(此选项可选)
{
var highFlags=GetHighFlags(opt);
如果(高标志!=0)
{
对于(ulong cFlag=1;cFlag!=0;cFlag首先,您可能需要重新考虑导致您使用超过32个标志的设计,因为这本身听起来很麻烦
除此之外,考虑到您只在执行位运算,所以如下所示的一些方法都是高效的(编译成一对夫妇指令),并且易于维护:
public enum Options : long
{
FlagA = 0x00000001,
// ...
FlagZ = 0x80000000,
// ...
HighFlags = 0xffff0000,
LowFlags = 0x0000ffff
}
然后,您可以通过执行(options&options.HighFlags)!=0来检查任何HighFlags
,并使用options&options.HighFlags
仅获取HighFlags
如果无法修改枚举,或不想依赖特定值,也可以在运行时将这些值组合在一起:
public static class OptionsHelper
{
private readonly static Options HighFlags = Options.FlagM
| Options.FlagN
// ...
| Options.FlagZ;
public static bool HasHighFlags(this Options opt)
{
return (opt & HighFlags) != 0;
}
public static Options GetHighFlags(this Options opt)
{
return (opt & HighFlags);
}
public static IEnumerable<Options> GetSetHighFlags(this Options opt)
{
var highFlags = GetHighFlags(opt);
if (highFlags != 0)
{
for (ulong cFlag = 1; cFlag != 0; cFlag <<= 1)
{
if ((highFlags & cFlag) != 0)
{
yield return (Options)cFlag;
}
}
}
}
}
公共静态类选项帮助器
{
私有只读静态选项HighFlags=Options.FlagM
|选项.FlagN
// ...
|Options.FlagZ;
公共静态bool HasHighFlags(此选项可选)
{
返回(可选和高标志)!=0;
}
公共静态选项GetHighFlags(此选项可选)
{
返回(选择和高标记);
}
公共静态IEnumerable GetSetHighFlags(此选项可选)
{
var highFlags=GetHighFlags(opt);
如果(高标志!=0)
{
对于(ulong cFlag=1;cFlag!=0;cFlag您可以简单地执行以下操作:
if (optons & 0xfe0000000000) // Typecasts will be needed
// One of those flags is set.
if (optons.HasFlag(0xfe0000000000)) // Typecasts will be needed
// One of those flags is set.
另外,请注意,较新版本的.NET支持options.HasFlag()
方法,这简化了确定是否定义了标志的过程
事实上,我没有测试它,但您应该能够执行以下操作:
if (optons & 0xfe0000000000) // Typecasts will be needed
// One of those flags is set.
if (optons.HasFlag(0xfe0000000000)) // Typecasts will be needed
// One of those flags is set.
您可以简单地执行以下操作:
if (optons & 0xfe0000000000) // Typecasts will be needed
// One of those flags is set.
if (optons.HasFlag(0xfe0000000000)) // Typecasts will be needed
// One of those flags is set.
另外,请注意,较新版本的.NET支持options.HasFlag()
方法,这简化了确定是否定义了标志的过程
事实上,我没有测试它,但您应该能够执行以下操作:
if (optons & 0xfe0000000000) // Typecasts will be needed
// One of those flags is set.
if (optons.HasFlag(0xfe0000000000)) // Typecasts will be needed
// One of those flags is set.
要检查是否设置了任何标志,请使用myOptions!=0
。要检索其值,只需按位AND(&
)它使用了标志本身。对不起。为了更清楚起见,编辑了我的问题。基本上,我正在尝试确定是否设置了FlagV上方的任何标志,如果设置了,该标志是什么。@arao6您的最后一个代码片段与return myOptions;
等效。基本上,在清除所有不关心的标志后,您只需要寻找LEATt设置的有效位,其中一些应该很容易适应C#。顺便说一句,你似乎要问的问题的答案(但不是你实际想要的,基于你问题的其余部分)更简单:确定是否有任何标志设置为W
,X
,Y
只是myOptions&(Options.W | Options.X | Options.Y)!=0
(根据myOptions
的类型进行必要的强制转换)。要检查是否设置了任何标志,请使用myOptions!=0
。检索其值,只需按位和(&
)它使用了标志本身。对不起。为了更清楚起见,编辑了我的问题。基本上,我正在尝试确定是否设置了FlagV上方的任何标志,如果设置了,该标志是什么。@arao6您的最后一个代码片段与return myOptions;
等效。基本上,在清除所有不关心的标志后,您只需要寻找LEATt设置的有效位,其中一些应该很容易适应C#。顺便说一句,你似乎要问的问题的答案(但不是你实际想要的,基于你问题的其余部分)更简单:确定是否有任何标志设置为W
,X
,Y
只是myOptions&(Options.W | Options.X | Options.Y)!=0
(根据myOptions
的类型进行必要的强制转换)。我希望可以接受多个答案:)您的方法