共用方式為


列舉型別(C# 參考)

列舉型別(或enum型別)是一種由基礎整數型別的一組具名常數所定義的值型別。 若要定義列舉型別,請使用 enum 關鍵詞並指定 列舉成員的名稱:

enum Season
{
    Spring,
    Summer,
    Autumn,
    Winter
}

根據預設,列舉成員的相關聯常數值屬於 類型 int;其開頭為零,並依定義文字順序增加一個。 您可以明確地將任何其他 整數數值 類型指定為列舉型別的基礎類型。 您也可以明確指定相關聯的常數值,如下列範例所示:

enum ErrorCode : ushort
{
    None = 0,
    Unknown = 1,
    ConnectionLost = 100,
    OutlierReading = 200
}

你無法在列舉型別的定義中定義方法。 若要為列舉型別新增功能,請建立 擴充成員

列舉型別 E 的預設值是由表達式 (E)0 所產生的值,即便零沒有對應的列舉成員。

從零隱含轉換

C# 允許從常值 0 隱含轉換成任何列舉類型,以及從 const 等於零的值進行隱含轉換。 當列舉不包含值為零的成員時,此行為可能會導致非預期的結果:

public enum GpioPort
{
    GpioA = 1,
    GpioB,
    GpioC,
    GpioD
}

public class ZeroConversionExample
{
    public static void Main()
    {
        // This compiles without warning but creates an invalid enum value
        GpioPort port1 = (GpioPort)0;
        Console.WriteLine($"port1: {port1}"); // Output: port1: 0

        // This also compiles due to implicit conversion from zero
        GpioPort port2 = GetPort(0);
        Console.WriteLine($"port2: {port2}"); // Output: port2: 0

        // Check if the enum value is valid
        bool isValid1 = Enum.IsDefined(typeof(GpioPort), port1);
        bool isValid2 = Enum.IsDefined(typeof(GpioPort), port2);
        Console.WriteLine($"port1 is valid: {isValid1}"); // Output: port1 is valid: False
        Console.WriteLine($"port2 is valid: {isValid2}"); // Output: port2 is valid: False

        // Safer approach - validate enum values
        if (Enum.IsDefined(typeof(GpioPort), 0))
        {
            GpioPort safePort = (GpioPort)0;
        }
        else
        {
            Console.WriteLine("Value 0 is not a valid GpioPort");
            // Handle the invalid case appropriately
        }
    }

    public static GpioPort GetPort(GpioPort port)
    {
        return port;
    }
}

在上述範例中,和 port1 都會port2指派 值0,但沒有GpioPort具有該值的成員。 Enum.IsDefined方法會確認這些列舉值無效。

這種隱含轉換存在,是因為 0 位元模式是所有結構型態的預設值,包括所有枚舉型別。 不過,它可以在您的程式代碼中引入 Bug。 若要避免這些問題:

  • 您幾乎應該一律在列舉中定義具有值 0 的成員。
  • 從數值類型轉換時,使用 Enum.IsDefined 來驗證列舉值。
  • 使用可能隱含轉換成列舉類型的數值參數時,請小心謹慎。

您可以使用列舉類型來表示一組互斥值或選擇組合的選擇。 若要表示選擇的組合,請將列舉型別定義為位旗標。

列舉型別作為位元標誌

如果您想要列舉類型代表選項的組合,請定義這些選項的列舉成員,讓個別選擇是位元欄位。 也就是說,這些列舉成員的相關值應該是兩個許可權。 然後,您可以使用 位邏輯運算符 | ,或 & 分別結合選項或交集選擇的組合。 若要指出列舉類型宣告位元欄,請將 Flags 屬性套用至它。 如下列範例所示,您也可以在列舉型別的定義中包含一些典型的組合。

[Flags]
public enum Days
{
    None      = 0b_0000_0000,  // 0
    Monday    = 0b_0000_0001,  // 1
    Tuesday   = 0b_0000_0010,  // 2
    Wednesday = 0b_0000_0100,  // 4
    Thursday  = 0b_0000_1000,  // 8
    Friday    = 0b_0001_0000,  // 16
    Saturday  = 0b_0010_0000,  // 32
    Sunday    = 0b_0100_0000,  // 64
    Weekend   = Saturday | Sunday
}

public class FlagsEnumExample
{
    public static void Main()
    {
        Days meetingDays = Days.Monday | Days.Wednesday | Days.Friday;
        Console.WriteLine(meetingDays);
        // Output:
        // Monday, Wednesday, Friday

        Days workingFromHomeDays = Days.Thursday | Days.Friday;
        Console.WriteLine($"Join a meeting by phone on {meetingDays & workingFromHomeDays}");
        // Output:
        // Join a meeting by phone on Friday

        bool isMeetingOnTuesday = (meetingDays & Days.Tuesday) == Days.Tuesday;
        Console.WriteLine($"Is there a meeting on Tuesday: {isMeetingOnTuesday}");
        // Output:
        // Is there a meeting on Tuesday: False

        var a = (Days)37;
        Console.WriteLine(a);
        // Output:
        // Monday, Wednesday, Saturday
    }
}

如需詳細資訊和範例,請參閱 System.FlagsAttribute API 參考頁面和 非獨佔成員和 API 參考頁面的 System.Enum Flags 屬性一節。

System.Enum 類型和列舉條件約束

System.Enum 類型是所有列舉型別的抽象基類。 它提供一些方法來取得列舉型別及其值的相關信息。 如需詳細資訊和範例,請參閱 System.Enum API 參考頁面。

您可以在 System.Enum 基類條件 約束中使用 ,以指定類型參數是列舉型別。 任何列舉型別也都滿足 struct 條件約束,用來指定類型參數是不可為 Null 的實值型別。

轉換次數

對於任何列舉型別,列舉型別與其基礎整數類型之間有明確的轉換。 如果您將列舉值 轉換成 其基礎類型,結果就是列舉成員的相關聯整數值。

public enum Season
{
    Spring,
    Summer,
    Autumn,
    Winter
}

public class EnumConversionExample
{
    public static void Main()
    {
        Season a = Season.Autumn;
        Console.WriteLine($"Integral value of {a} is {(int)a}");  // output: Integral value of Autumn is 2

        var b = (Season)1;
        Console.WriteLine(b);  // output: Summer

        var c = (Season)4;
        Console.WriteLine(c);  // output: 4
    }
}

Enum.IsDefined使用方法來判斷列舉類型是否包含具有特定關聯值的列舉成員。

對於任何列舉型別,分別有 Boxing 和 unboxing 轉換到 型別和從 System.Enum 類型轉換。

C# 語言規格

如需詳細資訊,請參閱 C# 語言規格的下列幾節:

另請參閱