簡體   English   中英

C# 標志枚舉按值或名稱切換

[英]C# flag enum toggle by value or name

我有一個 Flags enum ,想通過它的 ( long ) 值來切換一些值。

[Flags]
public enum Permissions : long
{
    Value0 = 0,
    Value1 = 0x1,
    Value2 = 0x2,
    Value3 = 0x4,
    //etc
}

我使用long字段通過EF將實際權限存儲在數據庫中,例如:

   public Permissions UsersPermissions { get; set; }

從客戶端,我一一獲取值以通過enum切換正確的值,因此如果數據庫字段包含

`Value1 | Value2 | Value3`

我得到 4 我必須從用戶的權限中刪除 Value3。

  • 如何通過長版本獲得正確的enum值?
  • 如何通過長表示在 UserPermissions 字段中切換一個值?

我已經嘗試過usersPermissions |= permissionValue但它說我不能在longPermission Types 上使用|=運算符。

您必須在適當的點對longPermissions進行一些轉換,如下所示:

Permissions perms = Permissions.Value1 | Permissions.Value2 | Permissions.Value3;
Console.WriteLine(perms); // Value1, Value2, Value3

long toRemove = 4;
// OR: long toRemove = (long) Permissions.Value3;

perms = (Permissions) ((long)perms & ~toRemove); // Use "& ~X" to remove bits set in X.

Console.WriteLine(perms); // Value1, Value2

這里重要的是~toRemove返回~toRemove的按位補toRemove ,從而為您提供一組位標志,您可以使用原始值&以關閉在toRemove中設置的所有位。

你必須投permslong ,以做到這一點&操作。

最后,通過&獲得所需的結果后,您必須將longPermissions以獲得正確的枚舉類型作為最終答案。

據我所知,您的輸入是一個數字,您希望它是一個Permissions 好吧,即使它不是離散值之一,您也可以直接轉換它。 如果它是標志值之一的組合,那甚至可以“弄清楚”。 C# 枚舉以這種方式進行強制轉換非常聰明。

這是一個代碼示例,可以執行您想要的操作

[Flags]
public enum TestEnum : long
{
    ValueNone = 0,  // You can't really "have" a Value0, it's an absence of values
    Value1 = 0x1,
    Value2 = 0x2,
    Value3 = 0x4,
    Value4 = 0x8
}

foreach(var enumVal in Enum.GetValues(typeof(TestEnum)))
{
    Console.WriteLine("val is: {0} long is: {1}", enumVal, (long)enumVal);
}

{
    Console.WriteLine("Start with 1 and 3, remove 3 from number");
    var testEnum = TestEnum.Value1 | TestEnum.Value3;
    Console.WriteLine("testEnum is: {0}({1})", testEnum, (long)testEnum);
    long testVal = 4;   // TestEnum.Value3
    var removeEnum = (TestEnum)testVal;
    removeEnum = ~removeEnum;
    testEnum &= removeEnum;
    Console.WriteLine("testEnum is: {0}({1})", testEnum, (long)testEnum);
}
{
    Console.WriteLine("Start with 1, 2, 4 and remove 1 and 4 from number");
    var testEnum = TestEnum.Value1 | TestEnum.Value2 | TestEnum.Value4;
    Console.WriteLine("testEnum is: {0}({1})", testEnum, (long)testEnum);
    long testVal = (long)TestEnum.Value1 | (long)TestEnum.Value4;   // Could also have added them
    var removeEnum = (TestEnum)testVal;
    Console.WriteLine("Removing: {0}({1})", removeEnum, (long)removeEnum);
    testEnum &= ~removeEnum;
    Console.WriteLine("testEnum is: {0}({1})", testEnum, (long)testEnum);
}

這是通過最后一個元素的值獲得枚舉限制的方法:

{
    // Check the value to see what the range of the enumeration is
    var lastVal = Enum.GetValues(typeof(TestEnum)).Cast<TestEnum>().Last();
    long limit = (long)lastVal * 2;
    Console.WriteLine("Limit of flags for TestEnum is: " + limit);
    Func<long, bool> testLambda = x => x < limit;
    Console.WriteLine("Value of {0} within limit: {1}", 14, testLambda(14));
    Console.WriteLine("Value of {0} within limit: {1}", 16, testLambda(16));
    Console.WriteLine("Value of {0} within limit: {1}", 200, testLambda(200));
    Console.WriteLine("Value of {0} within limit: {1}", 0, testLambda(0));
    Console.WriteLine("Out of range looks like: " + (TestEnum)17);
    Console.WriteLine("In range looks like: " + (TestEnum)14);
}

輸出:

val is: ValueNone long is: 0
val is: Value1 long is: 1
val is: Value2 long is: 2
val is: Value3 long is: 4
val is: Value4 long is: 8
Start with 1 and 3, remove 3 from number
testEnum is: Value1, Value3(5)
testEnum is: Value1(1)
Start with 1, 2, 4 and remove 1 and 4 from number
testEnum is: Value1, Value2, Value4(11)
Removing: Value1, Value4(9)
testEnum is: Value2(2)
Limit of flags for TestEnum is: 16
Value of 14 within limit: True
Value of 16 within limit: False
Value of 200 within limit: False
Value of 0 within limit: True
Out of range looks like: 17
In range looks like: Value2, Value3, Value4

我完全承認上面可能有更好的方法,但從根本上說,如果您有一個[Flags]枚舉,因此其中的所有內容在一定程度上都是“有效的”(所有組合都可以),只需檢查是否您的值超出范圍,然后將其從整數類型直接轉換為枚舉類型並稱其為一天。 一旦它是您的標志類型,您就可以毫無問題地使用按位運算符,因此請先執行此操作。

您必須對枚舉執行異或運算符。 因此,如果您的權限值具有:

  • 值1
  • 值2
  • 值3
  • 值4,

如果您想刪除 Value4,則必須執行以下操作:

var perm = Permissions.Value1 | Permissions.Value2 | Permissions.Value3 | Permissions.Value4;
perm = perm ^ Permissions.Value4;

暫無
暫無

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

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