枚举上最常见的C#按位运算
时间:2020-03-06 14:22:01 来源:igfitidea点击:
为了我的一生,我不记得如何在位域中进行设置,删除,切换或者测试。我不确定还是将它们混在一起,因为我很少需要这些。因此,拥有一个"位备忘单"将是不错的选择。
例如:
flags = flags | FlagsEnum.Bit4; // Set bit 4.
或者
if ((flags & FlagsEnum.Bit4)) == FlagsEnum.Bit4) // Is there a less verbose way?
我们能否举例说明所有其他常见操作,最好使用[Flags]枚举在Csyntax中进行?
解决方案
C ++操作是:&| ^〜(用于and,or,xor和非按位运算)。还感兴趣的是>>和<<,它们是位移位操作。
因此,要测试是否在标志中进行了设置,可以使用:
if(flags&8)//测试第4位是否已设置
习惯用法是使用按位或者等号运算符设置位:
flags |= 0x04;
为了清楚一点,习惯用法是按位取反:
flags &= ~0x04;
有时我们有一个偏移量来标识位,然后习惯用法是将这些与左移结合使用:
flags |= 1 << offset; flags &= ~(1 << offset);
C ++语法,假设第0位为LSB,并假设标志为无符号长整数:
检查是否设置:
flags & (1UL << (bit to test# - 1))
检查是否设置:
invert test !(flag & (...))
放:
flag |= (1UL << (bit to set# - 1))
清除:
flag &= ~(1UL << (bit to clear# - 1))
切换:
flag ^= (1UL << (bit to set# - 1))
要测试一下,我们可以执行以下操作:
(假设标志是一个32位数字)
测试位:
if((flags & 0x08) == 0x08)
(如果设置了位4,则它为true)
向后切换(1 0或者0 1):
flags = flags ^ 0x08;
将位4重置为零:
flags = flags & 0xFFFFFF7F;
我对这些扩展做了更多的工作,我们可以在这里找到代码
我写了一些扩展方法,这些方法扩展了我经常使用的System.Enum。
namespace Enum.Extensions { public static class EnumerationExtensions { public static bool Has<T>(this System.Enum type, T value) { try { return (((int)(object)type & (int)(object)value) == (int)(object)value); } catch { return false; } } public static bool Is<T>(this System.Enum type, T value) { try { return (int)(object)type == (int)(object)value; } catch { return false; } } public static T Add<T>(this System.Enum type, T value) { try { return (T)(object)(((int)(object)type | (int)(object)value)); } catch(Exception ex) { throw new ArgumentException( string.Format( "Could not append value from enumerated type '{0}'.", typeof(T).Name ), ex); } } public static T Remove<T>(this System.Enum type, T value) { try { return (T)(object)(((int)(object)type & ~(int)(object)value)); } catch (Exception ex) { throw new ArgumentException( string.Format( "Could not remove value from enumerated type '{0}'.", typeof(T).Name ), ex); } } } }
然后像下面这样使用
SomeType value = SomeType.Grapes; bool isGrapes = value.Is(SomeType.Grapes); //true bool hasGrapes = value.Has(SomeType.Grapes); //true value = value.Add(SomeType.Oranges); value = value.Add(SomeType.Apples); value = value.Remove(SomeType.Grapes); bool hasOranges = value.Has(SomeType.Oranges); //true bool isApples = value.Is(SomeType.Apples); //false bool hasGrapes = value.Has(SomeType.Grapes); //false