枚举按位运算返回错误值
Enum Bitwise operation returning wrong value
我有代表红色、蓝色、绿色和 None 的颜色选择 enum
。
[Flags]
public enum SelectedColor
{
None, Red, Blue, Green
}
当我创建一个新枚举并将其设置为 Red
和 Green
时,然后检查是否设置了 Blue
,它 returns true
。 Blue
从未在任何地方设置。
例如:
SelectedColor selectedColor = SelectedColor.Red;
selectedColor |= SelectedColor.Green; //Add Green to Selection
//Check if blue is set
Debug.Log("Blue Selected hasFlag? : " + hasFlag(selectedColor, SelectedColor.Blue));
//Check if blue is set
Debug.Log("Blue Selected isSet? : " + isSet(selectedColor, SelectedColor.Blue));
输出:
Blue Selected hasFlag? : False
Blue Selected isSet? : True
hasFlag 和 isSet 函数:
bool hasFlag(SelectedColor source, SelectedColor value)
{
int s1 = (int)source;
return Convert.ToBoolean((s1 & Convert.ToInt32(((int)value) == s1)));
}
bool isSet(SelectedColor source, SelectedColor critValue)
{
//return ((source & critValue) == critValue);
return ((source & critValue) != 0);
}
如您所见,我的 isSet
函数返回了错误的值。 return ((source & critValue) == critValue)
和 return ((source & critValue) != 0);
我都试过了,但都失败了。根据我对 SO 和 this post.
的研究,这应该有效
我的 hasFlag
函数没问题,但为什么 isSet
函数返回了错误的值?
请注意,我使用的是 .NET 3.5,所以我不能使用 .NET 4 枚举辅助函数,例如 HasFlag
。
如果您没有为枚举指定值,则会像这样为它们分配序列号:
[Flags]
public enum SelectedColor // WRONG
{
None = 0, // 000
Red = 1, // 001
Blue = 2, // 010
Green = 3 // 011 <-- Not the next power of two!
}
然后会发生这种情况:
selectedColor = SelectedColor.Red; // 001
selectedColor |= SelectedColor.Green; // (001 | 011 ) == 011, which is still Green
[Flags]
枚举需要使用2的幂,如下:
[Flags]
public enum SelectedColor // CORRECT
{
None = 0, // 000
Red = 1, // 001
Blue = 2, // 010
Green = 4 // 100
}
然后就可以正常工作了:
selectedColor = SelectedColor.Red; // 001
selectedColor |= SelectedColor.Green; // (001 | 100) == 101, which is Red, Green
尽管 Matthew 的回答是正确的,而且是一个很好的答案("maxed out version" 的主题 here),但我会保留它 "generic" 并且更简单一些换一种方式:与图层蒙版使用相同的行为。这里的限制是,您的枚举不能超过 32 个项目。
private void uncleFoo() {
enum myNATO { Adam, Bravo, Charlie, Delta } //my enum with NATO codes
int activeNATO = 0; //int to store selected NATO codes
//some testing here
activeNATO |= 1 << (int)myNATO.Adam;
activeNATO |= 1 << (int)myNATO.Bravo;
activeNATO |= 1 << (int)myNATO.Charlie;
Debug.Log(activeNATO);
Debug.Log("has Adam? " + (activeNATO & 1 << (int)myNATO.Adam));
Debug.Log("has Delta? " + (activeNATO & 1 << (int)myNATO.Delta));
}
显然,Debug.Log 将为 Adam 打印“1”,为 Delta 打印“0”。
希望对您有所帮助 ;)
我有代表红色、蓝色、绿色和 None 的颜色选择 enum
。
[Flags]
public enum SelectedColor
{
None, Red, Blue, Green
}
当我创建一个新枚举并将其设置为 Red
和 Green
时,然后检查是否设置了 Blue
,它 returns true
。 Blue
从未在任何地方设置。
例如:
SelectedColor selectedColor = SelectedColor.Red;
selectedColor |= SelectedColor.Green; //Add Green to Selection
//Check if blue is set
Debug.Log("Blue Selected hasFlag? : " + hasFlag(selectedColor, SelectedColor.Blue));
//Check if blue is set
Debug.Log("Blue Selected isSet? : " + isSet(selectedColor, SelectedColor.Blue));
输出:
Blue Selected hasFlag? : False
Blue Selected isSet? : True
hasFlag 和 isSet 函数:
bool hasFlag(SelectedColor source, SelectedColor value)
{
int s1 = (int)source;
return Convert.ToBoolean((s1 & Convert.ToInt32(((int)value) == s1)));
}
bool isSet(SelectedColor source, SelectedColor critValue)
{
//return ((source & critValue) == critValue);
return ((source & critValue) != 0);
}
如您所见,我的 isSet
函数返回了错误的值。 return ((source & critValue) == critValue)
和 return ((source & critValue) != 0);
我都试过了,但都失败了。根据我对 SO 和 this post.
我的 hasFlag
函数没问题,但为什么 isSet
函数返回了错误的值?
请注意,我使用的是 .NET 3.5,所以我不能使用 .NET 4 枚举辅助函数,例如 HasFlag
。
如果您没有为枚举指定值,则会像这样为它们分配序列号:
[Flags]
public enum SelectedColor // WRONG
{
None = 0, // 000
Red = 1, // 001
Blue = 2, // 010
Green = 3 // 011 <-- Not the next power of two!
}
然后会发生这种情况:
selectedColor = SelectedColor.Red; // 001
selectedColor |= SelectedColor.Green; // (001 | 011 ) == 011, which is still Green
[Flags]
枚举需要使用2的幂,如下:
[Flags]
public enum SelectedColor // CORRECT
{
None = 0, // 000
Red = 1, // 001
Blue = 2, // 010
Green = 4 // 100
}
然后就可以正常工作了:
selectedColor = SelectedColor.Red; // 001
selectedColor |= SelectedColor.Green; // (001 | 100) == 101, which is Red, Green
尽管 Matthew 的回答是正确的,而且是一个很好的答案("maxed out version" 的主题 here),但我会保留它 "generic" 并且更简单一些换一种方式:与图层蒙版使用相同的行为。这里的限制是,您的枚举不能超过 32 个项目。
private void uncleFoo() {
enum myNATO { Adam, Bravo, Charlie, Delta } //my enum with NATO codes
int activeNATO = 0; //int to store selected NATO codes
//some testing here
activeNATO |= 1 << (int)myNATO.Adam;
activeNATO |= 1 << (int)myNATO.Bravo;
activeNATO |= 1 << (int)myNATO.Charlie;
Debug.Log(activeNATO);
Debug.Log("has Adam? " + (activeNATO & 1 << (int)myNATO.Adam));
Debug.Log("has Delta? " + (activeNATO & 1 << (int)myNATO.Delta));
}
显然,Debug.Log 将为 Adam 打印“1”,为 Delta 打印“0”。
希望对您有所帮助 ;)