在使用Unity时,发现了if ((controller.collisionFlags & CollisionFlags.Sides) != 0)代码,发现是使用了C#枚举位运算,遂记录。

一、枚举

枚举是是名称与值的集合,枚举类型是值类型。

1
2
3
4
5
6
7
8
9
public enum Options
{
Insert, // =0
Update, // =1
Save, // =...
Delete,
Query
}

编译器会自动补充枚举,从零开始依次赋值。

二、位运算

我们可能需要多个枚举的组合来满足我们的需要。

位运算是针对二进制位进行的运算,常用的位运算主要有与(&), 或(|)和非(~)

1
2
//e.m:
1 & 0 = 0, 1 | 0 = 1, ~1 = 0

要使枚举类型具有位运算的能力,需要加上特性[FlagsAttribute]简写[Flags]。有些位处于on状态,有些处于off状态。所以通常在定义一个None=0的枚举符号。相对应的值都为2的指数倍。为的是后续的运算。例如Unity的CollisionFlagshideFlags

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Program
{
static void Main(string[] args)
{
OprationType opration = OprationType.Read | OprationType.Write;

Console.WriteLine(opration.ToString());
Console.Read();
}
}

[FlagsAttribute]
public enum OprationType
{
None = 0, //0000
Read=1, //0001
Write=2, //0010
Sport=4,//0100
Fuck=8//1000
}
//运行结果
//Read,Write

或运算之后想要去掉某个,可以使用-=

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Program
{
static void Main(string[] args)
{
OprationType opration = OprationType.Read | OprationType.Write; // 0001 | 0010 = 0011
opration -= OprationType.Write;
Console.WriteLine(opration.ToString());
Console.Read();
}
}

[FlagsAttribute]
public enum OprationType
{
None = 0,
Read=1,
Write=2,
}
//运行结果
//Read

我们可以根据“&”与操作进行权限判断,可以表示为:0011&0001=0001,后面0001==0001,符合条件,有[Insert]权限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Program
{
static void Main(string[] args)
{
OprationType opration = OprationType.Read | OprationType.Write;
if((opration & OperationType.Read) != 0){ //0011 & 0001 = 0001
Console.WriteLine(opration.ToString());
}
Console.Read();
}
}

[FlagsAttribute]
public enum OprationType
{
None = 0,
Read=1,
Write=2,
}