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

C# 進階:模擬字串型別的列舉型別

     編輯:關於C語言

前言:為何需要字串型別的列舉?

在 C# 中,列舉的底層型別只能是整數型別(byte、short、int、long 等),並不支援直接使用 string 作為成員值。然而,實際開發中常遇到需求:希望列舉成員能直接對應特定字串(如 HTML 顏色代碼 "#FF0000")。本文將示範如何透過類別模擬出「字串型別列舉」的行為,並探討其優缺點與 .NET Framework 內建的解決方案。

模擬字串列舉的核心設計

1. 私有建構子與靜態唯讀實例

列舉的特性是「透過成員初始化,而非建構子」。因此將建構子設為 private,並暴露 static readonly 欄位作為預定義實例:

public class Color
{
    private Color(string value) { m_Value = value; }
    private string m_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");
}

使用 readonly 而非 const,是因為 const 僅適用於編譯期常數,而這裡的實例是在執行期建立的。

2. 明確轉換運算子:雙向轉換

重載 explicit operator 實現 Color ⇄ string 的強制轉換:

// Color → string
public static explicit operator string(Color value) => value.m_Value;

// string → Color
public static explicit operator Color(string value)
{
    switch (value)
    {
        case "#FF0000": return Red;
        case "#00FF00": return Green;
        case "#0000FF": return Blue;
        default: throw new InvalidCastException();
    }
}

若傳入非預期字串,拋出 InvalidCastException 以保證型別安全。

3. 完整程式碼與等值比較說明

public class Color
{
    private Color(string value) { m_Value = value; }
    private string m_Value;

    public static explicit operator Color(string value) { /* ... */ }
    public static explicit operator string(Color value) => m_Value;

    public override string ToString() => m_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");
}

關於等值比較:所有實例皆源自靜態唯讀欄位,因此參考相等(ReferenceEquals)即可滿足需求,無需額外重載 Equals 或 ==/!=。

模擬方案的缺失與單一職責原則(SRP)違反

此 Color 類別同時扮演「列舉標識」與「資料載體」兩個角色:既要提供像列舉一樣的 Red、Green 成員,又要攜帶 "#FF0000" 這類資料。這違反了 SRP,導致擴充性極差:若需加入 Alpha 通道、支援 CMYK 轉換、或處理上百萬種顏色,程式碼將難以維護。

.NET Framework 內建的色彩處理架構

.NET 在 System.Drawing 命名空間提供了三個協作的類型,職責劃分清晰:

  • KnownColor 列舉:僅作為「具名顏色」的標識(如 Indigo、Desktop),不攜帶資料,比較極快。
  • Color 結構:真正的資料載體,包含 A、R、G、B 四通道,提供 FromKnownColor/ToKnownColor 轉換,並正確實作等值比較。
  • ColorTranslator 類別:專責 Color 與 HTML 顏色字串("#FF0000")之間的轉換(ToHtml/FromHtml)。

使用範例:

string desktopColorHtml = ColorTranslator.ToHtml(Color.FromKnownColor(KnownColor.Desktop));

這種「列舉做標識、結構做資料、工具類做轉換」的分層設計,才是符合 SRP 且經得起時間考驗的架構。

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