跳至頁尾內容
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] 屬性,這允許將枚舉視為位元域。 他解釋說,每個權限都使用位元運算來分配獨特的二進位值。

Tim 沒有使用增量數字(0, 1, 2, 3 等)來指派值,而是使用二的冪次方:

[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 示範如何使用位元運算來指派和組合權限。 他解釋了我們可以使用位元或運算()|`) 運算子的變數中:

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

這樣就能使用位元運算將 SQL、Redis 和 GitHub 權限指派給 timsPermissions 並儲存在一個變數中。

使用 Flags 檢查權限

Flags 的一個主要優勢是可以使用位元與運算(&)運算子檢查是否已設定特定權限。 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 也講解了怎樣使用位元與及非運算(~)運算子移除一個權限。 如果我們需要撤銷 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 的開發者建立內容?將您的專業知識轉化為額外收入!

Iron 支援團隊

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