跳過到頁腳內容
Iron Academy Logo
學習 C#
學習 C#

其他分類

理解 C# 標誌

Tim Corey
8m 32s

C# Flags 是一個強大但常被忽視的功能,它允許開發者使用位運算來管理許可權和選項。 在他的影片"Binary in C#: Flags in 10 minutes or less"中,Tim Corey 提供了一個清晰且精簡的解釋,說明了 Flags 的運作方式及如何有效地在 C# 中運用它們。 在這篇文章中,我們將分析 Tim 的解釋和影片中提供的見解,以更好地理解 C# Flags。

什麼是 Flags?

Tim 首先介紹了 Flags 的概念。 他解釋說 Flags 讓我們可以將多個值分配給單一變數,這在應用程式中用於管理許可權時特別有用。 為了說明這一點,Tim 建立了一個名為 SystemPermissions 的列舉,其中包括 SQL、WebServer、Redis、Azure、GitHub 和 BuildSystem 等許可權。

Tim 指出,若沒有使用 Flags,一個變數一次只能保存一個許可權。例如,如果我們嘗試將 SystemPermissions.GitHub 分配給一個使用者,就無法再分配 SystemPermissions.BuildSystem,除非使用陣列,但這樣管理起來非常麻煩。

沒有 Flags 的問題

此時,Tim 演示了傳統列舉賦值的局限性。 如果我們一次只能分配一個許可權,稍後檢查它們時需要遍歷整個陣列,這樣效率低下且不具擴展性。 如 Tim 所描述的,這將導致一個"醜陋"的實現,其中對多個許可權的管理變得麻煩。

引入 Flags 屬性

為了解決這個問題,Tim 引進了 [Flags] 屬性,這使得列舉可以被視為一個位域。 他解釋道,每個許可權都被分配了一個唯一的二進位值,通過位移運算來實現。

而不是逐一賦值遞增的數字 (0、1、2、3 等),Tim 使用二的冪數來分配值:

[Flags]
enum SystemPermissions
{
    None = 0,
    SQL = 1 << 0,       // 00000001
    WebServer = 1 << 1, // 00000010
    Redis = 1 << 2,     // 00000100
    Azure = 1 << 3,     // 00001000
    GitHub = 1 << 4,    // 00010000
    BuildSystem = 1 << 5 // 00100000
}
[Flags]
enum SystemPermissions
{
    None = 0,
    SQL = 1 << 0,       // 00000001
    WebServer = 1 << 1, // 00000010
    Redis = 1 << 2,     // 00000100
    Azure = 1 << 3,     // 00001000
    GitHub = 1 << 4,    // 00010000
    BuildSystem = 1 << 5 // 00100000
}

Tim 解釋道,移動位元確保了每個許可權有一個不重疊的唯一值,這樣能夠高效地組合多個許可權。

賦值與組合 Flags

接著 Tim 示範了如何使用位運算賦值與組合許可權。 他解釋說,我們可以使用位運算 OR (|) 運算符分配多個許可權給使用者:

SystemPermissions timsPermissions = SystemPermissions.SQL | SystemPermissions.Redis | SystemPermissions.GitHub;
SystemPermissions timsPermissions = SystemPermissions.SQL | SystemPermissions.Redis | SystemPermissions.GitHub;

這樣將 SQL、Redis 和 GitHub 許可權分配給 timsPermissions,並使用位運算將它們儲存在單一變數中。

使用 Flags 檢查許可權

Flags 的一個主要好處是可以使用位運算 AND (&) 檢查特定許可權是否被設置。 Tim 演示了如何驗證用戶是否擁有特定許可權:

if ((timsPermissions & SystemPermissions.SQL) == SystemPermissions.SQL)
{
    Console.WriteLine("Tim has SQL access.");
}
if ((timsPermissions & SystemPermissions.SQL) == SystemPermissions.SQL)
{
    Console.WriteLine("Tim has SQL access.");
}

Tim 強調這種方法比遍歷陣列效率高得多,因為它允許快速進行位運算比較。

移除許可權

Tim 還介紹了如何使用位運算 AND 和 NOT (~) 移除許可權。 如果我們需要從 timsPermissions 撤銷 SQL 許可權,可以這樣做:

timsPermissions &= ~SystemPermissions.SQL;
timsPermissions &= ~SystemPermissions.SQL;

這樣有效地移除了 SQL 許可權,同時保留其他許可權不變。

以二進制形式顯示 Flags

為了視覺化 Flags 的運作,Tim 建議將列舉值轉換為其二進制表示。 他使用了一個輔助方法來顯示許可權的二進制值:

Console.WriteLine(Convert.ToString((int)timsPermissions, 2));
Console.WriteLine(Convert.ToString((int)timsPermissions, 2));

Tim 解釋道,這有助於理解如何在列舉中設置和操作單個位元。

為什麼使用 Flags?

Tim 結尾時強調了在 C# 中使用 Flags 的好處:

  • 它們允許在一個變數中存儲多個值。
  • 它們使許可權管理更加有效率。
  • 它們簡化了使用位運算檢查和修改許可權的操作。

他還指出,Flags 在文件許可權、用戶角色和應用程式設置等場景中被廣泛使用。

最後的想法

在整個影片中,Tim Corey 明確而實用地演示了 C# Flags 的運作方式。 通過使用 [Flags] 屬性和位運算,我們可以有效地管理多個許可權而無需複雜的數據結構。 如果您處理的許可權或設定需要多個值,Flags 是簡化實施過程的優秀工具。

想要親身了解,請查看 Tim Corey 的影片,他逐步解釋了這些概念。Flags 起初可能看起來很複雜,但一旦了解它們的二進制特性,它們便成為 C# 開發中極其有用的功能。

Hero Worlddot related to 理解 C# 標誌
Hero Affiliate related to 理解 C# 標誌

通過分享您所愛的東西賺得更多

您是否在為使用.NET、C#、Java、Python或Node.js的開發者創建內容?將您的專業知識轉化為額外收入!

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我