位掩码枚举的通用单标志枚举

问题描述 投票:1回答:2

我正在使用具有几个位标记枚举的代码库工作,这些枚举看起来像这样

public enum BitMask
{
    None = 0,

    OptionA = 1 << 0,
    OptionB = 1 << 1,

    OptionAandB = OptionA | OptionB,

    All = ~0
} 

我可以使用此迭代所有枚举值

public IEnumerable<T> EnumValues<T>()
{
    return Enum.GetValues(typeof(T)).Cast<T>();
}

我正在寻找一种通用方法,仅对单个标志值进行迭代,在这种情况下为OptionAOptionB不是 NoneOptionAandBAll。我可以将其强制转换为long并检测单个标志,因为它们是2的幂,因此在此处进行快速搜索可以发现这]

public bool IsPowerOfTwo(long val)
{
    return (val != 0) && ((val & (val-1)) == 0) ;
}

Nongeneric版本工作正常

public IEnumerable<BitMask> SingleFlagBitMaskValues()
{
    return Enum.GetValues(typeof(BitMask))
               .Cast<BitMask>()
               .Where(e => IsPowerOfTwo((long)e));
}

但是通用版本无法编译,因为它不喜欢强制转换为long

public IEnumerable<TEnum> SingleFlagEnumValues<TEnum>()
{
    return Enum.GetValues(typeof(TEnum))
        .Cast<TEnum>()
        .Where(e => IsPowerOfTwo((long)e));
}

可以解决吗?

我正在使用具有几个位标记枚举的代码库,这些枚举看起来像这个公共枚举BitMask {None = 0,OptionA = 1 << 0,OptionB = 1 << 1,OptionAandB = ...

c# enums ienumerable bitmask
2个回答
2
投票

由于许多重载,您可以使用Convert.ToInt64


2
投票

如果您实际需要的只是“设置了一个位”,那就是弹出计数测试。方便地,为此存在一个CPU内部函数,可以从.NET Core中轻松使用它:

© www.soinside.com 2019 - 2024. All rights reserved.