萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> 程式語言綜合

C# 位運算完整指南:權限掩碼、旗標枚舉與高效能技巧

C# 支援的位運算子

運算子名稱範例用途
&位元 ANDa & b檢查旗標、遮罩、清除位
|位元 ORa | b設定旗標、合併權限
^位元 XORa ^ b切換旗標、差異比較、簡單加密
~位元 NOT (補數)~a反轉旗標、建立遮罩
<<左移a << n乘 2^n、建立位掩碼 (1<<n)
>>右移a >> n除 2^n、提取高位

支援型別:byte、sbyte、short/ushort、int/uint、long/ulong、char、enum (底層整數型別)。

經典應用:權限掩碼模式

[Flags] // 關鍵:讓 ToString()、HasFlag()、IDE 顯示支援旗標語義
public enum Permission : uint {
    None      = 0,
    View      = 1 << 0,  // 1  (0b0000_0001)
    Add       = 1 << 1,  // 2  (0b0000_0010)
    Edit      = 1 << 2,  // 4  (0b0000_0100)
    Delete    = 1 << 3,  // 8  (0b0000_1000)
    Approve   = 1 << 4,  // 16 (0b0001_0000)
    Admin     = 1 << 5,  // 32 (0b0010_0000)
    SuperAdmin = View | Add | Edit | Delete | Approve | Admin // 63
}

權限檢查核心邏輯

Permission userPerm = Permission.View | Permission.Edit | Permission.Delete; // 13 (0b0000_1101)

// 1. 擁有「單一」權限
bool canEdit = (userPerm & Permission.Edit) != 0; // true

// 2. 擁有「所有」指定權限 (AND 掩碼)
bool canEditAndDelete = (userPerm & (Permission.Edit | Permission.Delete)) == (Permission.Edit | Permission.Delete);

// 3. .NET 4.0+ 內建 HasFlag (內部同樣用 &)
bool canView = userPerm.HasFlag(Permission.View); // true

// 4. 新增權限
userPerm |= Permission.Add; // userPerm = userPerm | Permission.Add

// 5. 移除權限
userPerm &= ~Permission.Delete; // userPerm = userPerm & ~Permission.Delete

// 6. 切換權限
userPerm ^= Permission.Approve;

完整控制台演示程式

using System;

[Flags]
enum Power : int {
    None = 0, View = 1, Add = 2, Edit = 4, Delete = 8, Approve = 16, Super = 32
}

class BitDemo {
    static void Main() {
        int value = 126; // 0b0111_1110 (View+Add+Edit+Delete+Approve+Super)
        int[] powers = { 1, 2, 4, 8, 16, 32, 64 };

        Console.WriteLine($"值 {value} 包含權限:");
        for (int i = 0; i < powers.Length; i++) {
            if ((value & powers[i]) != 0)
                Console.WriteLine($"  Bit {i} (1<<{i}={powers[i]})");
        }

        Console.WriteLine($"\n位運算演示 (value=126, mask=4):");
        Console.WriteLine($"AND  : 126 & 4   = {value & 4}");   // 4
        Console.WriteLine($"OR   : 126 | 4   = {value | 4}");   // 126
        Console.WriteLine($"XOR  : 126 ^ 4   = {value ^ 4}");   // 122
        Console.WriteLine($"LEFT : 126 << 4  = {value << 4}");  // 2016
        Console.WriteLine($"RIGHT: 126 >> 4  = {value >> 4}");  // 7
        Console.WriteLine($"NOT  : ~126      = {~value}");      // -127 (補數)
    }
}

進階技巧與最佳實踐

  1. FlagsAttribute 是文檔也是工具: 加上 [Flags] 讓 ToString() 輸出 "View, Add, Edit"、HasFlag 可用、VS 除錯器顯示友善。
  2. 選擇合適底層型別: uint/ulong 避免符號位干擾,支援更多旗標 (32/64 位)。
  3. 避免魔術數字: 永遠用 1 << n 定義旗標,語義自述。
  4. 位運算優先級: & > ^ > |;複雜表達式**務必加括號**。
  5. Enum.HasFlag 效能: 裝箱開銷;極熱路徑改用 (perm & flag) != 0。
  6. 交換兩變數 (無暫存變數): a ^= b; b ^= a; a ^= b; (教學用,實務可讀性差不推薦)。
  7. 快速判斷 2 的冪次: (n & (n-1)) == 0 && n > 0。
  8. 取模 2^n: x & (n-1) (n 為 2 的冪次)。

結語

位運算是「零開銷抽象」的極致體現:**用整數位元組合表示集合,用邏輯門電路速度完成集合運算**。掌握 [Flags] enum + & | ^ ~ << >> 組合拳,能在權限系統、狀態機、網路協定解析、圖形學、資料壓縮等場景寫出極簡高效的代碼。

copyright © 萬盛學電腦網 all rights reserved