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

C# 模擬字串型列舉:從需求分析到 .NET Framework 內建方案

     編輯:關於C語言

問題背景

C# 列舉底層型別僅支援整數類型(byte、int、long 等),不支援 string。但實務上常需「具名常數」對應「字串值」(如顏色十六進位代碼 "#FF0000")。

方案一:類別模擬列舉(Type-Safe Enum Pattern)

核心技巧:

  • private 建構子防止外部實例化。
  • public static readonly 欄位暴露預定義實例。
  • 多載 explicit operator string / explicit operator Color 實現雙向轉換。
  • 因所有實例皆為同一靜態物件,天然支援參考相等比較,無需多載 ==/Equals。
public sealed class Color
{
    private readonly string _value;

    private Color(string value) => _value = value;

    // 預定義實例
    public static readonly Color Red = new Color("#FF0000");
    public static readonly Color Green = new Color("#00FF00");
    public static readonly Color Blue = new Color("#0000FF");

    // 實例 → 字串
    public static explicit operator string(Color c) => c._value;

    // 字串 → 實例(嚴格驗證)
    public static explicit operator Color(string hex)
    {
        return hex switch
        {
            "#FF0000" => Red,
            "#00FF00" => Green,
            "#0000FF" => Blue,
            _ => throw new InvalidCastException($"無效色碼: {hex}")
        };
    }

    public override string ToString() => _value;
}

用法示範

Color c1 = Color.Red;
string hex = (string)c1;           // "#FF0000"
Color c2 = (Color)"#00FF00";       // Color.Green
Debug.Assert(c2 == Color.Green);   // 參考相等,直接比較

設計缺陷與單一職責原則 (SRP) 違反

此模式同時承擔「列舉標識」與「資料載體」雙重責任:

  • 若需擴充 Alpha 通道、CMYK 轉換、色彩空間運算,類別會膨脹難以維護。
  • 硬編碼色碼對應關係,違反開放封閉原則。

.NET Framework 內建完整方案:System.Drawing

框架以三個類型分工合作,完美遵循 SRP:

類型職責關鍵成員
KnownColor (enum)具名顏色標識(系統色、Web 色)Red, Desktop, ControlText...
Color (struct)色彩資料載體(ARGB 通道)A/R/G/B 屬性, FromKnownColor(), ToKnownColor(), 運算子多載
ColorTranslator (class)色彩與 HTML/Win32/OLE 格式互轉ToHtml(), FromHtml(), ToWin32(), ToOle()

組合使用範例

using System.Drawing;

// 取得系統桌面背景色的 HTML 色碼
string desktopHtmlColor = ColorTranslator.ToHtml(
    Color.FromKnownColor(KnownColor.Desktop)
);

// 從 HTML 色碼建立 Color 結構
Color myColor = ColorTranslator.FromHtml("#336699");
byte alpha = myColor.A;  // 255
byte red = myColor.R;    // 51

結論

  • 簡單場景:自訂 sealed class 模擬列舉即可,開發快速。
  • 涉及色彩運算、多格式互轉、系統色整合:直接使用 System.Drawing 三件組,架構乾淨、功能完整、效能優異。
  • 核心啟示:職責單一、組合優於繼承,框架設計值得深入研讀。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved