首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 枚舉實戰精髓:位運算、本地化、ORM 映射三大進階模式

     編輯:關於C語言

枚舉不僅是常量集合,更是領域建模的利器。本文總結實戰中三大進階用法:Flags 位運算組合、泛型本地化擴展、ORM 無縫映射,讓枚舉從「代碼裡的數字」變為「業務語言的直觀表達」。

一、Flags 屬性:類型安全的位掩碼

為枚舉標記 [Flags],賦予 2 的冪次值,即可進行集合式運算:

[Flags]
public enum MicrosoftTech {
    CSharp       = 1,   // 0001
    AspNetMvc    = 2,   // 0010
    SqlServer    = 4,   // 0100
    Wcf          = 8,   // 1000
    Silverlight  = 16   // 10000
}

核心操作

// 組合技能
var skills = MicrosoftTech.CSharp | MicrosoftTech.AspNetMvc; // 0011 = 3

// 檢測是否擁有某技能
bool hasCSharp = (skills & MicrosoftTech.CSharp) != 0; // true

// 移除技能
skills &= ~MicrosoftTech.AspNetMvc; // 0011 & 1101 = 0001

// 切換技能
skills ^= MicrosoftTech.SqlServer; // 翻轉第 3 位

// 遍歷所有包含的標誌
foreach (MicrosoftTech tech in Enum.GetValues(typeof(MicrosoftTech))) {
    if ((skills & tech) != 0) Console.WriteLine(tech);
}

優勢:編譯器保證類型安全,IDE 智能提示,避免魔術數字,ToString() 自動輸出 "CSharp, AspNetMvc"。

二、泛型本地化:枚舉變身多語言字典

利用 ResourceManager + 泛型,一行代碼獲取本地化顯示名:

public static class EnumExtensions {
    private static readonly ResourceManager _res = 
        new ResourceManager("Resources.Enums", Assembly.GetExecutingAssembly());

    public static string GetDisplayName(this T value) where T : Enum {
        string key = $"{typeof(T).Name}.{value}";
        return _res.GetString(key) ?? value.ToString();
    }

    public static List> GetLocalizedList() where T : Enum {
        return Enum.GetValues(typeof(T))
            .Cast()
            .Select(v => new KeyValuePair(
                Convert.ToInt32(v), v.GetDisplayName()))
            .ToList();
    }
}

資源文件 (Resources.Enums.resx):

NameValue (zh-CN)Value (en-US)
MicrosoftTech.CSharpC#C#
MicrosoftTech.AspNetMvcASP.NET MVCASP.NET MVC
MicrosoftTech.SqlServerSQL ServerSQL Server

用法:

var tech = MicrosoftTech.CSharp;
Console.WriteLine(tech.GetDisplayName()); // "C#"

var list = EnumExtensions.GetLocalizedList();
// 綁定到下拉框:Value=數值, Text=本地化名稱

三、ORM 映射:消除魔術數字,強類型領域模型

以 LINQ to SQL / Entity Framework 為例:

public enum CustomerType {
    Trader = 0,
    Supplier = 1,
    Logistics = 2
}

[Table("Customers")]
public class Customer {
    [Column] public int Id { get; set; }
    [Column] public string Name { get; set; }
    
    // 數據庫存 int,實體屬性為強類型枚舉
    [Column(Name = "CustomerType")] 
    public CustomerType Type { get; set; }
}

// 查詢
var traders = db.Customers.Where(c => c.Type == CustomerType.Trader).ToList();

// 生成 SQL: SELECT ... WHERE CustomerType = 0
// 無需硬編碼 0/1/2,重構安全,業務語義清晰

進階:值轉換器 (EF Core 2.1+)

protected override void OnModelCreating(ModelBuilder modelBuilder) {
    modelBuilder.Entity()
        .Property(e => e.Type)
        .HasConversion(); // 顯式指定數值轉換
}

避坑指南

  • [Flags] 枚舉值必須是 2 的冪次,否則位運算邏輯錯誤
  • 不要修改已發布枚舉的數值:會導致數據庫存儲值、序列化數據語義變更。新增項目只能追加
  • 預留「未知/無效」值:None = 0,便於判斷是否賦值
  • 大型枚舉考慮用類代替:若需屬性、方法、繼承,枚舉不再適用
  • 序列化注意:JSON.NET 默認序列化為數字,需配置 StringEnumConverter 輸出字符串

決策速查:何時用枚舉?

場景推薦備選
固定業務狀態集 (訂單狀態、用戶角色)Enum查表 + 外鍵
需組合的標誌集 (權限、特性、配置開關)[Flags] Enum位掩碼 int
需本地化顯示、描述、圖標等豐富元數據Enum + Resource/Attribute類 + 靜態實例
頻繁新增、運行時動態擴展數據庫表 + 緩存-
需行為、邏輯、驗證類 (Smart Enum 模式)-

結語

枚舉是 C# 最被低估的領域建模工具。Flags 賦予集合代數能力,泛型擴展實現國際化解耦,ORM 映射消除魔術數字——三招合一,讓枚舉成為業務語言在代碼中的精確投影。下次定義 enum Status { A, B, C } 時,請問自己:它需要組合嗎?需要多語言嗎?需要進數據庫嗎?答案在其中。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved