申请[Flags]
真正做什么?
我知道它会改变行为Enum.ToString
,但它会做什么吗?(例如,不同的编译器或运行时行为等)
编辑:是的,我知道它记录了枚举旨在用作按位标志的事实,并且将它应用于位标志更合乎逻辑.我更多地询问具体的行为变化,而不是一般的编程实践.
虽然修改一些老的C++代码,我在几个跑bitflags定义为枚举.
enum FooFlags
{
FooFlag1 = 1 << 0,
FooFlag2 = 1 << 1,
FooFlag3 = 1 << 2
// etc...
};
Run Code Online (Sandbox Code Playgroud)
这并不罕见,但是一旦你开始组合标志就会让你感到困扰,你会丢失类型信息.
int flags = FooFlag1 | FooFlag2; // We've lost the information that this is a set of flags relating to *Foo*
Run Code Online (Sandbox Code Playgroud)
一种替代方法是将标志声明为#defines或const积分,因此按位运算不会转换类型(可能).这个问题是它允许我们的位设置与不相关的标志,通过整数或其他枚举混合.
我熟悉std :: bitset和boost :: dynamic_bitset,但两者都不是为解决我的问题而设计的.我正在寻找的东西就像C#的FlagsAttribute.
我的问题是,对于(更多)类型安全的位标志,还有哪些其他解决方案?
我将在下面发布我自己的解决方案.
我有一个数据模型,其位域定义如下:
alter table MemberFlags add column title varchar(50) not null default '';
alter table MemberFlags add column value integer( 3) not null default 0;
insert into MemberFlags (title, value) values
("Blacklisted", 1),
("Special Guest", 2),
("Attend Ad-hoc Sessions", 4),
("Attend VIP Sessions", 8),
("Access Facility A", 16),
("Access Facility B", 32)
Run Code Online (Sandbox Code Playgroud)
像这样使用:
alter table Membership add column title varchar(50) not null default '';
alter table Membership add column flags integer( 3) not null default 0;
insert into Membership (title, flags) …
Run Code Online (Sandbox Code Playgroud) 可能重复:
C#int到枚举转换
是否有可能将int转换为标志组合枚举?因此,如果
[Flags]
public enum Foo {a = 0x80,
b = 0x40,
c = ...,
...
h = 0x1,
i = 0};
Run Code Online (Sandbox Code Playgroud)
是否可以(或某种可能)做
Foo fooInstance = (Foo)6;
Run Code Online (Sandbox Code Playgroud)
那fooInstance
将是00000110?
谢谢!
目前我正在使用枚举代表一个小游戏实验中的状态.我声明他们是这样的:
namespace State {
enum Value {
MoveUp = 1 << 0, // 00001 == 1
MoveDown = 1 << 1, // 00010 == 2
MoveLeft = 1 << 2, // 00100 == 4
MoveRight = 1 << 3, // 01000 == 8
Still = 1 << 4, // 10000 == 16
Jump = 1 << 5
};
}
Run Code Online (Sandbox Code Playgroud)
这样我就可以这样使用它们:
State::Value state = State::Value(0);
state = State::Value(state | State::MoveUp);
if (mState & State::MoveUp)
movement.y -= mPlayerSpeed;
Run Code Online (Sandbox Code Playgroud)
但我想知道这是否是实现位标志的正确方法.是否有特殊的容器标志容器?我听说过std::bitset
,这是我应该用的吗?你知道更高效的东西吗?
我做得对吗? …
正在研究如何通过使用flags属性和bitwize运算符(见下文)对enums进行装饰来将枚举用作位标志.
.NET框架中是否存在使用此模式的任何位置?我喜欢这个,但想看一些更真实的例子
[Flags]
enum Days2 : int
{
None = 0x0,
Sunday = 0x1,
Monday = 0x2,
Tuesday = 0x4,
Wednesday = 0x8,
Thursday = 0x10,
Friday = 0x20,
Saturday = 0x40
}
Days2 meetingDays = Days2.Tuesday | Days2.Thursday;
// Set an additional flag using bitwise OR.
meetingDays = meetingDays | Days2.Friday;
Console.WriteLine("Meeting days are {0}", meetingDays);
Run Code Online (Sandbox Code Playgroud) 假设,为了这个例子,我试图解析一个文件,该文件指定记录中的两个任意字节代表星期几,因此:
DayOfWeek:
- 0 = Monday
- 1 = Tuesday
- 2 = Wednesday
- 3 = Thursday
- 4 = Friday
- 5 = Saturday
- 6 = Sunday
- 7-15 = Reserved for Future Use
Run Code Online (Sandbox Code Playgroud)
我可以定义一个枚举来映射到这个字段,因此:
public enum DaysOfWeek
{
Monday = 0,
Tuesday = 1,
Wednesday = 2,
Thursday = 3,
Friday = 4,
Saturday = 5,
Sunday = 6
ReservedForFutureUse
}
Run Code Online (Sandbox Code Playgroud)
但是如何定义有效值ReservedForFutureUse
呢?理想情况下,我想做的事情如下:
public enum DaysOfWeek
{
Monday = 0,
Tuesday = 1,
Wednesday = …
Run Code Online (Sandbox Code Playgroud) 编辑:似乎大多数人误解了我的问题.
我知道枚举是如何运作的,我知道二进制.我想知道为什么带有[Flags]属性的枚举是按原样设计的.
原帖:
这可能是重复的,但我没有找到任何其他帖子,所以这里.
我打赌它背后有一些很好的理由,我发现它有点容易出错.
[Flag]
public enum Flagged
{
One, // 0
Two, // 1
Three, // 2
Four, // 3
}
Flagged f; // Defaults to Flagged.One = 0
f = Flagged.Four;
(f & Flagged.One) != 0; // Sure.. One defaults to 0
(f & Flagged.Two) != 0; // 3 & 1 == 1
(f & Flagged.Three) != 0; // 3 & 2 == 2
Run Code Online (Sandbox Code Playgroud)
如果做到这样的话会不会更有意义?
[Flag]
public enum Flagged
{
One = 1 << 0, …
Run Code Online (Sandbox Code Playgroud) 我试图在我的项目中了解更多有关此内容的信息.
我目前基本上有这个:
unsigned char flags = 0; //8 bits
flags |= 0x2; //apply random flag
if(flags & 0x2) {
printf("Opt 2 set");
}
Run Code Online (Sandbox Code Playgroud)
现在我希望做一些更复杂的事情,我想要做的是应用这样的三个标志:
flags = (0x1 | 0x2 | 0x4);
Run Code Online (Sandbox Code Playgroud)
然后删除标志0x1
,并0x2
从它?我以为我可以做这样的事情应用按位NOT(和按位AND来应用它):
flags &= ~(0x1 | 0x2);
Run Code Online (Sandbox Code Playgroud)
显然,当我检查时,他们会留在那里或者某种方式.
我也不知道如何检查它们是否不存在于位标志中(所以我无法检查我之前的代码是否有效),它会是这样的吗?
if(flags & ~0x2)
printf("flag 2 not set");
Run Code Online (Sandbox Code Playgroud)
我无法从我最近的搜索中找到适用于此的任何资源,我愿意学习这些来教别人,我真的很感兴趣.如果这令人困惑或简单,我道歉.
考虑这个课程:
public class MyClassOfMystery {
public static final int NO_FLAGS = ~0;
public static final int FIRST_FLAG = 1;
public static final int SECOND_FLAG = 1 << 1;
public static final int THIRD_FLAG = 1 << 2;
public static final int FOURTH_FLAG = 1 << 3;
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {NO_FLAGS, FIRST_FLAG, SECOND_FLAG, THIRD_FLAG, FOURTH_FLAG})
public @interface MysteryFlags { }
... set flags, get flags, and use flags stuff.
}
Run Code Online (Sandbox Code Playgroud)
我经常创建这样的东西,并发现能够遍历所有可用的标志是有用的MysteryFlags
.
我可以遍历设置的值MysteryFlags
吗?
这是我尝试过的:
这印刷 …
bitflags ×10
enums ×6
c# ×5
.net ×3
c++ ×3
c ×1
c++11 ×1
database ×1
django ×1
django-admin ×1
flags ×1
java ×1
python ×1
std-bitset ×1
type-safety ×1