C# 确定具有FlagsAttribute的枚举是否具有唯一的位值

C# 确定具有FlagsAttribute的枚举是否具有唯一的位值,c#,.net,enums,bit-manipulation,C#,.net,Enums,Bit Manipulation,考虑以下枚举: [Flags] public enum EnumWithUniqueBitFlags { None = 0, One = 1, Two = 2, Four = 4, Eight = 8, } [Flags] public enum EnumWithoutUniqueFlags { None = 0, One = 1, Two = 2, Four = 4, Five = 5, } 第一个具有这样的值

考虑以下枚举:

[Flags]
public enum EnumWithUniqueBitFlags
{
    None = 0,
    One = 1,
    Two = 2,
    Four = 4,
    Eight = 8,
}

[Flags]
public enum EnumWithoutUniqueFlags
{
    None = 0,
    One = 1,
    Two = 2,
    Four = 4,
    Five = 5,
}
第一个具有这样的值:任何组合都将产生唯一的位组合,而第二个不会。我需要通过编程来确定这一点。到目前为止,我只检查了每个值是否都是2的幂,但这是因为此代码将用于使用其他人开发的枚举,所以不实用

var values = Enum.GetValues(typeof(TEnum)).OfType<TEnum>().ToList();

for (int i = 0; i < values.Count; i++)
{
    if (((int) ((object) values [i])) != ((int) Math.Pow(2, i)))
    {
        throw (new Exception("Whatever."));
    }
}

请忽略枚举派生自哪个整数类型以及值可能为负值的事实。

要唯一,枚举必须没有与其他枚举值相同的位。可以使用

for (int i = 0; i < values.Count; ++i)
{
  for (int j = 0; j < values.Count; ++j)
  {
    if (i != j && ((values[i] & values[j]) != 0))
        throw new Exception(...);
  }
}
for(int i=0;i
您可以将枚举值的按位或与枚举值的算术和进行比较:

var values = Enum.GetValues(typeof(EnumWithoutUniqueFlags))
    .OfType<EnumWithoutUniqueFlags>().Select(val => (int)val).ToArray();

bool areBitsUnique = values.Aggregate(0, (acc, val) => acc | val) == values.Sum();

我会将枚举强制转换为uint,对0x0执行按位not,使用xor,如果下一个值小于上一个值,则会发生冲突

public static bool CheckEnumClashing<TEnum>()
{
    uint prev = 0;
    uint curr = 0;


   prev = curr = ~curr;

    foreach(var target in Enum.GetValues(typeof(TEnum)).Select(a=>(uint)a))
    {
        curr ^=target;

        if( curr <= prev )
            return false;

        prev = curr; 
    }

    return true;
}
公共静态bool CheckEnumClashing()
{
uint-prev=0;
uint curr=0;
上一次=当前=~curr;
foreach(Enum.GetValues中的var目标(typeof(TEnum)).Select(a=>(uint)a))
{
curr^=目标;

如果(curr A flags枚举定义的值不是二的幂是公共的-命名以二的幂定义的状态的叠加状态可能很有用。如果枚举值是例如
1
3
?或任何其他具有另一个公共位但不是最高位的值,该怎么办。@Dmitry你说得对,感谢heads up,将尝试修复此错误,但不适用于以下输入:
new int[4]{-9827265564,-98240129410}
。由智能单元测试(又名Microsoft Pex)确定。它似乎适用于所有正值。如果允许负值,则至少需要三个值才能找到错误。@非常感谢usr。请修改我编辑的帖子。@Dmitry:枚举中的一个或多个值是否为零有关系?@RaheelKhan零值在枚举中,不影响方法的返回值。我添加了一个新方法,并检查重复项是否为零。请修改。
private static bool AreEnumBitsUnique<T>()
{
    int mask = 0;
    foreach (int val in Enum.GetValues(typeof(T)))
    {
        if ((mask & val) != 0)
            return false;
        mask |= val;
    }
    return true;
}
private static bool AreEnumBitsUnique<T>()
{
    int mask = 0;
    int index = 0;
    foreach (int val in Enum.GetValues(typeof(T)))
    {
        if ((mask & val) != 0)  // If `val` and `mask` have common bit(s)
            return false;
        if (val == 0 && index != 0) // If more than one zero value in the enum
            return false;
        mask |= val;
        index += 1;
    }
    return true;
}
public static bool CheckEnumClashing<TEnum>()
{
    uint prev = 0;
    uint curr = 0;


   prev = curr = ~curr;

    foreach(var target in Enum.GetValues(typeof(TEnum)).Select(a=>(uint)a))
    {
        curr ^=target;

        if( curr <= prev )
            return false;

        prev = curr; 
    }

    return true;
}