簡體   English   中英

如何檢查是否設置了多個枚舉標志?

[英]How do I check if more than one enum flag is set?

我只想知道是否設置了一個枚舉標志,而不是哪個。 我目前的想法是檢查它是否是 2 的冪。有沒有更好的方法內置到枚舉類型中?

[Flags]
enum Foo
{
Flag1 = 0x01,
Flag2 = 0x02,
Flag3 = 0x04,
Flag4 = 0x08,
Flag5 = 0x10,
Flag6 = 0x20,
Flag7 = 0x40,
Flag8 = 0x80
}

private bool ExactlynOneFlagSet(Foo myFoo)
{
  var x = (byte) myFoo;
  return (x != 0) && ((x & (x - 1)) == 0); //Check if a power of 2
}

if(!ExactlynOneFlagSet(Foo myFoo))
{
   //Do something
}

它是一個位操作!

if ((myFoo & (myFoo -1)) != 0) //has more than 1 flag

該語句檢查myFoo的值是否不是 2 的冪。 或者,反之亦然,語句(myFoo & (myFoo -1)) == 0檢查二的冪。 這個想法是只有單個標志值是二的冪。 設置多個標志將導致myFoo值的非二次myFoo

更多信息可以在這個對類似問題的回答中找到: https : //stackoverflow.com/a/1662162/2404788

有關位操作的更多信息,請訪問http://en.wikipedia.org/wiki/Bitwise_operation

private bool ExatlyOneFlagSet(Foo myFoo)
{
  return !myFoo.ToString().Contains(',');
}

如果枚舉沒有定義明確的標志組合,您可以檢查枚舉中是否定義了該值:

private bool ExactlynOneFlagSet(Foo myFoo)
{
    return Enum.IsDefined(typeof(Foo), myFoo);
}

如果您使用 .NET Core 3.0+,則可以使用PopCount ,它返回uintulong中“1”位的數量並使用POPCNT CPU 指令(如果 CPU 支持 SSE4,否則它將使用軟件回退)。

public static bool ExactlyOneFlagSet(Foo foo)
{
    return BitOperations.PopCount((ulong)foo) == 1;
}
Foo one = Foo.Flag1;
Foo two = Foo.Flag1 | Foo.Flag2;

Console.WriteLine(ExactlyOneFlagSet(one)); //true
Console.WriteLine(ExactlyOneFlagSet(two)); //false

正如雅各布在評論中解釋的那樣,您的方法根本不正確。 就我個人而言,我總是避免進行數學編程,尤其是在邏輯方面。 因此,我的解決方案類似於“如果我想知道計數為 1,則對其進行計數並將其與第一進行比較”。

這里是:

    public static bool OneIsSet(Type enumType, byte value)
    {
        return Enum.GetValues(enumType).Cast<byte>().Count(v => (value & v) == v) == 1;
    }

    public static bool OneIsSet(Type enumType, int value)
    {
        return Enum.GetValues(enumType).Cast<byte>().Count(v => (value & v) == v) == 1;
    }

你可以像這樣將它用於你的 foo 類型:

   var toReturnFalse = (byte)(foo.Flag1 | foo.Flag2);
   var toReturnTrue = (byte)foo.Flag1;
   var trueWillBeReturned = OneIsSet(typeof(foo), toReturnTrue);
   var falseWillBeReturned = OneIsSet(typeof(foo), toReturnFalse);

我相信可以使用泛型和類型處理方法以更通用的方式編寫這些方法。 但是,我包括了最常見的枚舉基本類型的方法,這些方法是 int 和 byte。 但是您也可以為 short 和其他類型編寫相同的代碼。 您也可以在代碼中內聯代碼。 它只有一行代碼。

同樣使用此方法,您可以查看設置標志的數量是否為兩個或更多。 如果設置標志的計數等於“n”,則以下代碼返回 true。

   Enum.GetValues(enumType).Cast<byte>().Count(v => (value & v) == v) == n;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM