Enum 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
提供列舉的基類。
public ref class Enum abstract : ValueType, IComparable, IConvertible, IFormattable
public ref class Enum abstract : ValueType, IComparable, IConvertible, ISpanFormattable
public ref class Enum abstract : ValueType, IComparable, IFormattable
public abstract class Enum : ValueType, IComparable, IConvertible, IFormattable
public abstract class Enum : ValueType, IComparable, IConvertible, ISpanFormattable
[System.Serializable]
public abstract class Enum : ValueType, IComparable, IConvertible, IFormattable
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class Enum : ValueType, IComparable, IConvertible, IFormattable
public abstract class Enum : ValueType, IComparable, IFormattable
type Enum = class
inherit ValueType
interface IComparable
interface IConvertible
interface IFormattable
type Enum = class
inherit ValueType
interface IComparable
interface IConvertible
interface IFormattable
interface ISpanFormattable
type Enum = class
inherit ValueType
interface IComparable
interface IConvertible
interface ISpanFormattable
interface IFormattable
[<System.Serializable>]
type Enum = class
inherit ValueType
interface IComparable
interface IFormattable
interface IConvertible
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type Enum = class
inherit ValueType
interface IComparable
interface IFormattable
interface IConvertible
type Enum = class
inherit ValueType
interface IComparable
interface IFormattable
Public MustInherit Class Enum
Inherits ValueType
Implements IComparable, IConvertible, IFormattable
Public MustInherit Class Enum
Inherits ValueType
Implements IComparable, IConvertible, ISpanFormattable
Public MustInherit Class Enum
Inherits ValueType
Implements IComparable, IFormattable
- 繼承
- 衍生
- 屬性
- 實作
範例
下列範例示範如何使用 列舉來表示具名值,以及另一個列舉來表示具名位字段。
using System;
public class EnumTest {
enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday };
enum BoilingPoints { Celsius = 100, Fahrenheit = 212 };
[Flags]
enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 };
public static void Main() {
Type weekdays = typeof(Days);
Type boiling = typeof(BoilingPoints);
Console.WriteLine("The days of the week, and their corresponding values in the Days Enum are:");
foreach ( string s in Enum.GetNames(weekdays) )
Console.WriteLine( "{0,-11}= {1}", s, Enum.Format( weekdays, Enum.Parse(weekdays, s), "d"));
Console.WriteLine();
Console.WriteLine("Enums can also be created which have values that represent some meaningful amount.");
Console.WriteLine("The BoilingPoints Enum defines the following items, and corresponding values:");
foreach ( string s in Enum.GetNames(boiling) )
Console.WriteLine( "{0,-11}= {1}", s, Enum.Format(boiling, Enum.Parse(boiling, s), "d"));
Colors myColors = Colors.Red | Colors.Blue | Colors.Yellow;
Console.WriteLine();
Console.WriteLine($"myColors holds a combination of colors. Namely: {myColors}");
}
}
open System
type Days =
| Saturday = 0
| Sunday = 1
| Monday = 2
| Tuesday = 3
| Wednesday = 4
| Thursday = 5
| Friday = 6
type BoilingPoints =
| Celsius = 100
| Fahrenheit = 212
[<Flags>]
type Colors =
| Red = 1
| Green = 2
| Blue = 4
| Yellow = 8
let weekdays = typeof<Days>
let boiling = typeof<BoilingPoints>
printfn "The days of the week, and their corresponding values in the Days Enum are:"
for s in Enum.GetNames weekdays do
printfn $"""{s,-11}= {Enum.Format(weekdays, Enum.Parse(weekdays, s), "d")}"""
printfn "\nEnums can also be created which have values that represent some meaningful amount."
printfn "The BoilingPoints Enum defines the following items, and corresponding values:"
for s in Enum.GetNames boiling do
printfn $"""{s,-11}= {Enum.Format(boiling, Enum.Parse(boiling, s), "d")}"""
let myColors = Colors.Red ||| Colors.Blue ||| Colors.Yellow
printfn $"\nmyColors holds a combination of colors. Namely: {myColors}"
Public Class EnumTest
Enum Days
Saturday
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
End Enum
Enum BoilingPoints
Celsius = 100
Fahrenheit = 212
End Enum
<Flags()> _
Enum Colors
Red = 1
Green = 2
Blue = 4
Yellow = 8
End Enum
Public Shared Sub Main()
Dim weekdays As Type = GetType(Days)
Dim boiling As Type = GetType(BoilingPoints)
Console.WriteLine("The days of the week, and their corresponding values in the Days Enum are:")
Dim s As String
For Each s In [Enum].GetNames(weekdays)
Console.WriteLine("{0,-11} = {1}", s, [Enum].Format(weekdays, [Enum].Parse(weekdays, s), "d"))
Next s
Console.WriteLine()
Console.WriteLine("Enums can also be created which have values that represent some meaningful amount.")
Console.WriteLine("The BoilingPoints Enum defines the following items, and corresponding values:")
For Each s In [Enum].GetNames(boiling)
Console.WriteLine("{0,-11} = {1}", s, [Enum].Format(boiling, [Enum].Parse(boiling, s), "d"))
Next s
Dim myColors As Colors = Colors.Red Or Colors.Blue Or Colors.Yellow
Console.WriteLine()
Console.WriteLine("myColors holds a combination of colors. Namely: {0}", myColors)
End Sub
End Class
備註
列舉是一組具名常數,其基礎類型為任何整數類型。 如果未明確宣告基礎類型, Int32 則會使用 。
Enum 是 .NET 中所有列舉的基類。 列舉類型是由 enum C# 中的 關鍵詞、 EnumVisual Basic 中的 ...End Enum 建構和 type F# 中的 關鍵詞所定義。
Enum 提供方法來比較這個類別的實例、將實例的值轉換為其字串表示法、將數位的字串表示轉換為這個類別的實例,以及建立指定列舉和值的實例。
您也可以將枚舉視為位元欄位。 如需詳細資訊,請參閱 非獨佔成員和 Flags 屬性 一節和 FlagsAttribute。
建立列舉類型
程序設計語言通常會提供語法來宣告列舉,其中包含一組具名常數及其值。 下列範例說明 C#、F# 和 Visual Basic 用來定義列舉的語法。 它會建立名為 ArrivalStatus 的列舉,其具有三個成員: ArrivalStatus.Early、 ArrivalStatus.OnTime和 ArrivalStatus.Late。 請注意,在所有情況下,列舉不會明確繼承自 Enum;繼承關聯性是由編譯程式隱含處理。
public enum ArrivalStatus { Unknown=-3, Late=-1, OnTime=0, Early=1 };
type ArrivalStatus =
| Late = -1
| OnTime = 0
| Early = 1
Public Enum ArrivalStatus1 As Integer
Late = -1
OnTime = 0
Early = 1
End Enum
Warning
您絕對不應該建立其基礎型別為非整數或 Char的列舉型別。 雖然您可以使用反映來建立這類列舉型別,但使用所產生型別的方法呼叫並不可靠,也可能會擲回其他例外狀況。
具現化列舉類型
您可以宣告變數,並將其中一個列舉常數指派給它,來具現化列舉類型,就像具現化任何其他實值類型一樣。 下列範例會建立一個 ArrivalStatus,其值為 ArrivalStatus.OnTime。
public class Example
{
public static void Main()
{
ArrivalStatus status = ArrivalStatus.OnTime;
Console.WriteLine($"Arrival Status: {status} ({status:D})");
}
}
// The example displays the following output:
// Arrival Status: OnTime (0)
let status = ArrivalStatus.OnTime
printfn $"Arrival Status: {status} ({status:D})"
// The example displays the following output:
// Arrival Status: OnTime (0)
Public Module Example1
Public Sub Main()
Dim status As ArrivalStatus1 = ArrivalStatus1.OnTime
Console.WriteLine("Arrival Status: {0} ({0:D})", status)
End Sub
End Module
' The example displays the following output:
' Arrival Status: OnTime (0)
您也可以使用下列方式具現化列舉值:
藉由使用特定程式語言的功能,將整數值轉型為列舉值(如在 C# 中),或轉換為列舉值(如在 Visual Basic 中)。 下列範例會以這種方式建立
ArrivalStatus物件,其值為ArrivalStatus.Early。ArrivalStatus status2 = (ArrivalStatus)1; Console.WriteLine($"Arrival Status: {status2} ({status2:D})"); // The example displays the following output: // Arrival Status: Early (1)let status2 = enum<ArrivalStatus> 1 printfn $"Arrival Status: {status2} ({status2:D})" // The example displays the following output: // Arrival Status: Early (1)Dim status2 As ArrivalStatus2 = CType(1, ArrivalStatus2) Console.WriteLine("Arrival Status: {0} ({0:D})", status2) ' The example displays the following output: ' Arrival Status: Early (1)藉由呼叫其隱含無參數建構函式。 如下列範例所示,在此情況下,列舉實例的基礎值為0。 不過,這不一定是列舉中有效常數的值。
ArrivalStatus status1 = new ArrivalStatus(); Console.WriteLine($"Arrival Status: {status1} ({status1:D})"); // The example displays the following output: // Arrival Status: OnTime (0)let status1 = ArrivalStatus() printfn $"Arrival Status: {status1} ({status1:D})" // The example displays the following output: // Arrival Status: OnTime (0)Dim status1 As New ArrivalStatus2() Console.WriteLine("Arrival Status: {0} ({0:D})", status1) ' The example displays the following output: ' Arrival Status: OnTime (0)藉由呼叫 Parse 或 TryParse 方法來剖析包含列舉中常數名稱的字串。 如需詳細資訊,請參閱剖析 列舉值 一節。
列舉最佳做法
當您定義列舉類型時,建議您使用下列最佳做法:
如果您尚未定義值為 0 的列舉成員,請考慮建立
None列舉常數。 根據預設,用於列舉的記憶體會由 Common Language Runtime 初始化為零。 因此,如果您未定義值為零的常數,列舉會在建立時包含不合法的值。如果應用程式必須表示的明顯預設案例,請考慮使用列舉常數,其值為零來表示它。 如果沒有預設案例,請考慮使用列舉常數,其值為零的列舉常數來指定任何其他列舉常數未表示的案例。
請勿指定保留供日後使用的列舉常數。
當您定義接受列舉常數做為值的方法或屬性時,請考慮驗證值。 您可以將數值轉換為列舉類型,即使該數值在列舉中未定義,這就是原因。
列舉型別的其他最佳做法,其常數是位欄位列在 非獨佔成員和 Flags 屬性區段 中。
使用列舉執行作業
當您建立列舉時,無法定義新的方法。 不過,列舉型別會從 Enum 類別繼承一組完整的靜態和實例方法。 下列各節除了使用列舉值時常用的數個其他方法之外,也會調查這些方法中的大部分。
執行轉換
您可以在列舉成員與其基礎類型之間進行轉換,方法是使用類型轉換運算子(在 C# 和 F# 中),或轉換運算子(在 Visual Basic 中)。 在 F# 中,也會使用 函 enum 式。 下列範例使用轉換或轉換運算符來執行從整數到列舉值,以及從列舉值轉換為整數的轉換。
int value3 = 2;
ArrivalStatus status3 = (ArrivalStatus)value3;
int value4 = (int)status3;
let value3 = 2
let status3 = enum<ArrivalStatus> value3
let value4 = int status3
Dim value3 As Integer = 2
Dim status3 As ArrivalStatus2 = CType(value3, ArrivalStatus2)
Dim value4 As Integer = CInt(status3)
類別 Enum 也包含 ToObject 方法,可將任何整數型別的值轉換成列舉值。 下列範例會使用 ToObject(Type, Int32) 方法將 Int32 轉換成 ArrivalStatus 值。 請注意,由於ToObject會傳回Object類型的值,因此仍可能需要使用轉型或轉換運算符將物件轉換為列舉類型。
int number = -1;
ArrivalStatus arrived = (ArrivalStatus)ArrivalStatus.ToObject(typeof(ArrivalStatus), number);
let number = -1
let arrived = ArrivalStatus.ToObject(typeof<ArrivalStatus>, number) :?> ArrivalStatus
Dim number As Integer = -1
Dim arrived As ArrivalStatus2 = CType(ArrivalStatus2.ToObject(GetType(ArrivalStatus2), number), ArrivalStatus2)
將整數轉換成列舉值時,可以指派不是列舉成員的值。 若要避免這種情況,您可以先將整數傳遞至 IsDefined 方法,再執行轉換。 下列範例會使用這個方法來判斷整數值陣列中的元素是否可以轉換成 ArrivalStatus 值。
using System;
public class Example3
{
public static void Main()
{
int[] values = { -3, -1, 0, 1, 5, Int32.MaxValue };
foreach (var value in values)
{
ArrivalStatus status;
if (Enum.IsDefined(typeof(ArrivalStatus), value))
status = (ArrivalStatus)value;
else
status = ArrivalStatus.Unknown;
Console.WriteLine($"Converted {value:N0} to {status}");
}
}
}
// The example displays the following output:
// Converted -3 to Unknown
// Converted -1 to Late
// Converted 0 to OnTime
// Converted 1 to Early
// Converted 5 to Unknown
// Converted 2,147,483,647 to Unknown
open System
type ArrivalStatus =
| Unknown = -3
| Late = -1
| OnTime = 0
| Early = 1
let values = [ -3; -1; 0; 1; 5; Int32.MaxValue ]
for value in values do
let status =
if Enum.IsDefined(typeof<ArrivalStatus>, value) then
enum value
else
ArrivalStatus.Unknown
printfn $"Converted {value:N0} to {status}"
// The example displays the following output:
// Converted -3 to Unknown
// Converted -1 to Late
// Converted 0 to OnTime
// Converted 1 to Early
// Converted 5 to Unknown
// Converted 2,147,483,647 to Unknown
Public Enum ArrivalStatus4 As Integer
Unknown = -3
Late = -1
OnTime = 0
Early = 1
End Enum
Module Example4
Public Sub Main()
Dim values() As Integer = {-3, -1, 0, 1, 5, Int32.MaxValue}
For Each value In values
Dim status As ArrivalStatus4
If [Enum].IsDefined(GetType(ArrivalStatus4), value) Then
status = CType(value, ArrivalStatus4)
Else
status = ArrivalStatus4.Unknown
End If
Console.WriteLine("Converted {0:N0} to {1}", value, status)
Next
End Sub
End Module
' The example displays the following output:
' Converted -3 to Unknown
' Converted -1 to Late
' Converted 0 to OnTime
' Converted 1 to Early
' Converted 5 to Unknown
' Converted 2,147,483,647 to Unknown
雖然 Enum 類別提供明確的 IConvertible 介面實作,以便將列舉值轉換為整數類型,但您應該使用 Convert 類別的方法,例如 ToInt32,來進行這些轉換。 下列範例說明如何使用 GetUnderlyingType 方法以及 Convert.ChangeType 方法,將列舉值轉換成其基礎類型。 請注意,此範例不需要在編譯時期知道列舉的基礎類型。
ArrivalStatus status = ArrivalStatus.Early;
var number = Convert.ChangeType(status, Enum.GetUnderlyingType(typeof(ArrivalStatus)));
Console.WriteLine($"Converted {status} to {number}");
// The example displays the following output:
// Converted Early to 1
let status = ArrivalStatus.Early
let number = Convert.ChangeType(status, Enum.GetUnderlyingType typeof<ArrivalStatus>)
printfn $"Converted {status} to {number}"
// The example displays the following output:
// Converted Early to 1
Dim status As ArrivalStatus5 = ArrivalStatus5.Early
Dim number = Convert.ChangeType(status, [Enum].GetUnderlyingType(GetType(ArrivalStatus5)))
Console.WriteLine("Converted {0} to {1}", status, number)
' The example displays the following output:
' Converted Early to 1
剖析列舉值
Parse和 TryParse 方法可讓您將列舉值的字串表示轉換成該值。 字串表示可以是列舉常數的名稱或基礎值。 請注意,如果字串表示的數字能夠轉換為列舉的基礎類型值,即使這些數字不是該特定列舉的成員,解析方法也可以成功轉換。 若要避免這種情況, IsDefined 可以呼叫 方法,以確保剖析方法的結果是有效的列舉值。 此範例說明此方法,並示範對 Parse(Type, String) 和 Enum.TryParse<TEnum>(String, TEnum) 方法的呼叫。 請注意,非泛型剖析方法會傳回一個物件,您可能需要在 C# 和 F# 中進行型別轉換,或在 Visual Basic 中將其轉換為適當的列舉類型。
string number = "-1";
string name = "Early";
try
{
ArrivalStatus status1 = (ArrivalStatus)Enum.Parse(typeof(ArrivalStatus), number);
if (!(Enum.IsDefined(typeof(ArrivalStatus), status1)))
status1 = ArrivalStatus.Unknown;
Console.WriteLine($"Converted '{number}' to {status1}");
}
catch (FormatException)
{
Console.WriteLine($"Unable to convert '{number}' to an ArrivalStatus value.");
}
ArrivalStatus status2;
if (Enum.TryParse<ArrivalStatus>(name, out status2))
{
if (!(Enum.IsDefined(typeof(ArrivalStatus), status2)))
status2 = ArrivalStatus.Unknown;
Console.WriteLine($"Converted '{name}' to {status2}");
}
else
{
Console.WriteLine($"Unable to convert '{number}' to an ArrivalStatus value.");
}
// The example displays the following output:
// Converted '-1' to Late
// Converted 'Early' to Early
let number = "-1"
let name = "Early"
try
let status1 = Enum.Parse(typeof<ArrivalStatus>, number) :?> ArrivalStatus
let status1 =
if not (Enum.IsDefined(typeof<ArrivalStatus>, status1) ) then
ArrivalStatus.Unknown
else
status1
printfn $"Converted '{number}' to {status1}"
with :? FormatException ->
printfn $"Unable to convert '{number}' to an ArrivalStatus value."
match Enum.TryParse<ArrivalStatus> name with
| true, status2 ->
let status2 =
if not (Enum.IsDefined(typeof<ArrivalStatus>, status2) ) then
ArrivalStatus.Unknown
else
status2
printfn $"Converted '{name}' to {status2}"
| _ ->
printfn $"Unable to convert '{number}' to an ArrivalStatus value."
// The example displays the following output:
// Converted '-1' to Late
// Converted 'Early' to Early
Dim number As String = "-1"
Dim name As String = "Early"
Dim invalid As String = "32"
Try
Dim status1 As ArrivalStatus8 = CType([Enum].Parse(GetType(ArrivalStatus8), number), ArrivalStatus8)
If Not [Enum].IsDefined(GetType(ArrivalStatus8), status1) Then status1 = ArrivalStatus8.Unknown
Console.WriteLine("Converted '{0}' to {1}", number, status1)
Catch e As FormatException
Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus8 value.",
number)
End Try
Dim status2 As ArrivalStatus8
If [Enum].TryParse(Of ArrivalStatus8)(name, status2) Then
If Not [Enum].IsDefined(GetType(ArrivalStatus8), status2) Then status2 = ArrivalStatus8.Unknown
Console.WriteLine("Converted '{0}' to {1}", name, status2)
Else
Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus8 value.",
number)
End If
' The example displays the following output:
' Converted '-1' to Late
' Converted 'Early' to Early
格式化列舉值
您可以透過呼叫靜態方法 Format 以及實例方法 ToString 的多載,將列舉值轉換為其字串表示。 您可以使用格式字串來控制列舉值以字串表示的精確方式。 如需詳細資訊,請參閱 列舉格式字串。 下列範例會使用每個支援的列舉格式字串 (“G” 或 “g”、“D” 或 “d”、“X” 或 “x” 和 “F” 或 “f” 將列舉的成員 ArrivalStatus 轉換成其字串表示法。
string[] formats = { "G", "F", "D", "X" };
ArrivalStatus status = ArrivalStatus.Late;
foreach (var fmt in formats)
Console.WriteLine(status.ToString(fmt));
// The example displays the following output:
// Late
// Late
// -1
// FFFFFFFF
let formats = [ "G"; "F"; "D"; "X" ]
let status = ArrivalStatus.Late
for fmt in formats do
printfn $"{status.ToString fmt}"
// The example displays the following output:
// Late
// Late
// -1
// FFFFFFFF
Dim formats() As String = {"G", "F", "D", "X"}
Dim status As ArrivalStatus6 = ArrivalStatus6.Late
For Each fmt As String In formats
Console.WriteLine(status.ToString(fmt))
Next
' The example displays the following output:
' Late
' Late
' -1
' FFFFFFFF
遍歷列舉成員
類型 Enum 未實作IEnumerable或IEnumerable<T>介面,如此您就無法使用 foreach(在 C# 中)、for..in(在 F# 中)或 For Each(在 Visual Basic 中)的建構來逐一查看集合的成員。 不過,您可以透過兩種方式之一列舉成員。
您可以呼叫 GetNames 方法來擷取包含列舉成員名稱的字串數位。 接下來,針對字串陣列的每個元素,您可以呼叫 Parse 方法,將字元串轉換成其相等的列舉值。 下列範例說明此方法。
string[] names = Enum.GetNames(typeof(ArrivalStatus)); Console.WriteLine($"Members of {typeof(ArrivalStatus).Name}:"); Array.Sort(names); foreach (var name in names) { ArrivalStatus status = (ArrivalStatus)Enum.Parse(typeof(ArrivalStatus), name); Console.WriteLine($" {status} ({status:D})"); } // The example displays the following output: // Members of ArrivalStatus: // Early (1) // Late (-1) // OnTime (0) // Unknown (-3)let names = Enum.GetNames typeof<ArrivalStatus> printfn $"Members of {nameof ArrivalStatus}:" let names = Array.sort names for name in names do let status = Enum.Parse(typeof<ArrivalStatus>, name) :?> ArrivalStatus printfn $" {status} ({status:D})" // The example displays the following output: // Members of ArrivalStatus: // Early (1) // Late (-1) // OnTime (0) // Unknown (-3)Dim names() As String = [Enum].GetNames(GetType(ArrivalStatus7)) Console.WriteLine("Members of {0}:", GetType(ArrivalStatus7).Name) Array.Sort(names) For Each name In names Dim status As ArrivalStatus7 = CType([Enum].Parse(GetType(ArrivalStatus7), name), ArrivalStatus7) Console.WriteLine(" {0} ({0:D})", status) Next ' The example displays the following output: ' Members of ArrivalStatus7: ' Early (1) ' Late (-1) ' OnTime (0) ' Unknown (-3)您可以呼叫 GetValues 方法來擷取陣列,其中包含列舉中的基礎值。 接下來,針對陣列的每個元素,您可以呼叫 ToObject 方法,將整數轉換成其相等的列舉值。 下列範例說明此方法。
var values = Enum.GetValues(typeof(ArrivalStatus)); Console.WriteLine($"Members of {typeof(ArrivalStatus).Name}:"); foreach (ArrivalStatus status in values) { Console.WriteLine($" {status} ({status:D})"); } // The example displays the following output: // Members of ArrivalStatus: // OnTime (0) // Early (1) // Unknown (-3) // Late (-1)let values = Enum.GetValues typeof<ArrivalStatus> printfn $"Members of {nameof ArrivalStatus}:" for status in values do printfn $" {status} ({status:D})" // The example displays the following output: // Members of ArrivalStatus: // OnTime (0) // Early (1) // Unknown (-3) // Late (-1)Dim values = [Enum].GetValues(GetType(ArrivalStatus7)) Console.WriteLine("Members of {0}:", GetType(ArrivalStatus7).Name) For Each value In values Dim status As ArrivalStatus7 = CType([Enum].ToObject(GetType(ArrivalStatus7), value), ArrivalStatus7) Console.WriteLine(" {0} ({0:D})", status) Next ' The example displays the following output: ' Members of ArrivalStatus7: ' OnTime (0) ' Early (1) ' Unknown (-3) ' Late (-1)
非獨佔成員和旗標屬性
列舉的一個常見用法是表示一組互斥值。 例如, ArrivalStatus 實體的值可以是 Early、 OnTime或 Late。
ArrivalStatus 實例的值反映一個以上的列舉常數是沒有意義的。
不過,在其他情況下,列舉物件的值可以包含多個列舉成員,而且每個成員都代表列舉值中的位字段。
FlagsAttribute屬性可用來指出列舉是由位欄位所組成。 例如,名為 Pets 的列舉可用來指出家庭中的寵物種類。 其定義方式如下。
[Flags]
public enum Pets
{
None = 0, Dog = 1, Cat = 2, Bird = 4, Rodent = 8,
Reptile = 16, Other = 32
};
[<Flags>]
type Pets =
| None = 0
| Dog = 1
| Cat = 2
| Bird = 4
| Rodent = 8
| Reptile = 16
| Other = 32
<Flags> Public Enum Pets As Integer
None = 0
Dog = 1
Cat = 2
Bird = 4
Rodent = 8
Reptile = 16
Other = 32
End Enum
然後,您可以如以下範例所示使用Pets列舉。
Pets familyPets = Pets.Dog | Pets.Cat;
Console.WriteLine($"Pets: {familyPets:G} ({familyPets:D})");
// The example displays the following output:
// Pets: Dog, Cat (3)
let familyPets = Pets.Dog ||| Pets.Cat
printfn $"Pets: {familyPets:G} ({familyPets:D})"
// The example displays the following output:
// Pets: Dog, Cat (3)
Dim familyPets As Pets = Pets.Dog Or Pets.Cat
Console.WriteLine("Pets: {0:G} ({0:D})", familyPets)
' The example displays the following output:
' Pets: Dog, Cat (3)
定義位列舉並套用 FlagsAttribute 屬性時,應該使用下列最佳做法。
只有在要對數值執行位運算(AND、OR、EXCLUSIVE OR)時,才能對列舉使用 FlagsAttribute 自定義屬性。
定義兩個乘冪的列舉常數,也就是 1、2、4、8 等等。 這表示合並列舉常數中的個別旗標不會重疊。
請考慮為常用的旗標組合建立列舉常數。 例如,如果您有一個用於檔案 I/O 操作的列舉,其中包含列舉常數
Read = 1和Write = 2,您可以考慮建立一個新的列舉常數ReadWrite = Read OR Write,這個常數是結合Read和Write旗標而成的。 此外,位元 OR 運算用於結合標誌在某些情況下可能被視為一種進階概念,而並非簡單任務所必需。如果您將負數定義為旗標列舉常數,請小心,因為許多旗標位置可能設定為 1,這可能會導致程式代碼混淆並鼓勵編碼錯誤。
測試數值中是否設定旗標的便利方式是呼叫 實例 HasFlag 方法,如下列範例所示。
Pets familyPets = Pets.Dog | Pets.Cat; if (familyPets.HasFlag(Pets.Dog)) Console.WriteLine("The family has a dog."); // The example displays the following output: // The family has a dog.let familyPets = Pets.Dog ||| Pets.Cat if familyPets.HasFlag Pets.Dog then printfn "The family has a dog." // The example displays the following output: // The family has a dog.Dim familyPets As Pets = Pets.Dog Or Pets.Cat If familyPets.HasFlag(Pets.Dog) Then Console.WriteLine("The family has a dog.") End If ' The example displays the following output: ' The family has a dog.它相當於在數值與旗標列舉常數之間執行位 AND 運算,它會將數值中的所有位設定為零,但不會對應至旗標,然後測試該作業的結果是否等於旗標列舉常數。 下列範例會加以說明。
Pets familyPets = Pets.Dog | Pets.Cat; if ((familyPets & Pets.Dog) == Pets.Dog) Console.WriteLine("The family has a dog."); // The example displays the following output: // The family has a dog.let familyPets = Pets.Dog ||| Pets.Cat if (familyPets &&& Pets.Dog) = Pets.Dog then printfn "The family has a dog." // The example displays the following output: // The family has a dog.Dim familyPets As Pets = Pets.Dog Or Pets.Cat If familyPets And Pets.Dog = Pets.Dog Then Console.WriteLine("The family has a dog.") End If ' The example displays the following output: ' The family has a dog.使用
None做為值為零之旗標列舉常數的名稱。 您無法在位元 AND 運算中使用None列舉常數來測試旗標,因為結果一律為零。 不過,您可以執行數值與None列舉常數之間的邏輯而非位比較,以判斷數值中的任何位是否已設定。 下列範例會加以說明。Pets familyPets = Pets.Dog | Pets.Cat; if (familyPets == Pets.None) Console.WriteLine("The family has no pets."); else Console.WriteLine("The family has pets."); // The example displays the following output: // The family has pets.let familyPets = Pets.Dog ||| Pets.Cat if familyPets = Pets.None then printfn "The family has no pets." else printfn "The family has pets." // The example displays the following output: // The family has pets.Dim familyPets As Pets = Pets.Dog Or Pets.Cat If familyPets = Pets.None Then Console.WriteLine("The family has no pets.") Else Console.WriteLine("The family has pets.") End If ' The example displays the following output: ' The family has pets.請勿只定義列舉值,以反映列舉本身的狀態。 例如,請勿定義只標記列舉結尾的列舉常數。 如果您需要判斷列舉的最後一個值,請明確檢查該值。 此外,如果範圍內的所有值都有效,您可以針對第一個和最後一個列舉常數執行範圍檢查。
新增列舉方法
因為列舉型別是由語言結構所定義,例如 enum (C#) 和 Enum (Visual Basic),所以您無法定義列舉型別的自定義方法,而不是繼承自 Enum 類別的方法。 不過,您可以使用擴充方法將功能新增至特定列舉類型。
在以下範例中,Grades 枚舉表示學生在課程中可能取得的字母評分。 名為 Passing 的擴充方法已新增到 Grades 類型中,讓該類型的每個實例現在都「知道」它是否代表通過的成績。 類別 Extensions 也包含靜態讀寫變數,可定義最低通過等級。 擴充方法的 Passing 傳回值會反映該變數的目前值。
using System;
// Define an enumeration to represent student grades.
public enum Grades { F = 0, D = 1, C = 2, B = 3, A = 4 };
// Define an extension method for the Grades enumeration.
public static class Extensions
{
public static Grades minPassing = Grades.D;
public static bool Passing(this Grades grade)
{
return grade >= minPassing;
}
}
class Example8
{
static void Main()
{
Grades g1 = Grades.D;
Grades g2 = Grades.F;
Console.WriteLine($"{g1} {(g1.Passing() ? "is" : "is not")} a passing grade.");
Console.WriteLine($"{g2} {(g2.Passing() ? "is" : "is not")} a passing grade.");
Extensions.minPassing = Grades.C;
Console.WriteLine("\nRaising the bar!\n");
Console.WriteLine($"{g1} {(g1.Passing() ? "is" : "is not")} a passing grade.");
Console.WriteLine($"{g2} {(g2.Passing() ? "is" : "is not")} a passing grade.");
}
}
// The example displays the following output:
// D is a passing grade.
// F is not a passing grade.
//
// Raising the bar!
//
// D is not a passing grade.
// F is not a passing grade.
open System
open System.Runtime.CompilerServices
// Define an enumeration to represent student grades.
type Grades =
| F = 0
| D = 1
| C = 2
| B = 3
| A = 4
let mutable minPassing = Grades.D
// Define an extension method for the Grades enumeration.
[<Extension>]
type Extensions =
[<Extension>]
static member Passing(grade) = grade >= minPassing
let g1 = Grades.D
let g2 = Grades.F
printfn $"""{g1} {if g1.Passing() then "is" else "is not"} a passing grade."""
printfn $"""{g2} {if g2.Passing() then "is" else "is not"} a passing grade."""
minPassing <- Grades.C
printfn "\nRaising the bar!\n"
printfn $"""{g1} {if g1.Passing() then "is" else "is not"} a passing grade."""
printfn $"""{g2} {if g2.Passing() then "is" else "is not"} a passing grade."""
// The exmaple displays the following output:
// D is a passing grade.
// F is not a passing grade.
//
// Raising the bar!
//
// D is not a passing grade.
// F is not a passing grade.
Imports System.Runtime.CompilerServices
' Define an enumeration to represent student grades.
Public Enum Grades As Integer
F = 0
D = 1
C = 2
B = 3
A = 4
End Enum
' Define an extension method for the Grades enumeration.
Public Module Extensions
Public minPassing As Grades = Grades.D
<Extension>
Public Function Passing(grade As Grades) As Boolean
Return grade >= minPassing
End Function
End Module
Public Module Example
Public Sub Main()
Dim g1 As Grades = Grades.D
Dim g2 As Grades = Grades.F
Console.WriteLine("{0} {1} a passing grade.",
g1, If(g1.Passing(), "is", "is not"))
Console.WriteLine("{0} {1} a passing grade.",
g2, If(g2.Passing(), "is", "is not"))
Console.WriteLine()
Extensions.minPassing = Grades.C
Console.WriteLine("Raising the bar!")
Console.WriteLine()
Console.WriteLine("{0} {1} a passing grade.",
g1, If(g1.Passing(), "is", "is not"))
Console.WriteLine("{0} {1} a passing grade.",
g2, If(g2.Passing(), "is", "is not"))
End Sub
End Module
' The example displays the following output:
' D is a passing grade.
' F is not a passing grade.
'
' Raising the bar!
'
' D is not a passing grade.
' F is not a passing grade.
建構函式
| 名稱 | Description |
|---|---|
| Enum() |
初始化 Enum 類別的新執行個體。 |
方法
| 名稱 | Description |
|---|---|
| CompareTo(Object) |
比較這個實例與指定的物件,並傳回其相對值的指示。 |
| Equals(Object) |
傳回值,指出這個實例是否等於指定的物件。 |
| Format(Type, Object, String) |
根據指定的格式,將指定列舉型別的指定值轉換為其相等字串表示。 |
| GetHashCode() |
傳回這個實例值的哈希碼。 |
| GetName(Type, Object) |
擷取指定列舉中具有指定值之常數的名稱。 |
| GetName<TEnum>(TEnum) |
擷取指定列舉型別中具有指定值之常數的名稱。 |
| GetNames(Type) |
擷取指定列舉中常數名稱的陣列。 |
| GetNames<TEnum>() |
擷取指定列舉型別中常數名稱的陣列。 |
| GetType() |
取得目前實例的 Type。 (繼承來源 Object) |
| GetTypeCode() |
傳回這個列舉成員之基礎型別的類型代碼。 |
| GetUnderlyingType(Type) |
傳回指定列舉的基礎型別。 |
| GetValues(Type) |
擷取指定列舉中常數值的陣列。 |
| GetValues<TEnum>() |
擷取指定列舉型別中常數值的陣列。 |
| GetValuesAsUnderlyingType(Type) |
擷取指定列舉中基礎類型常數值的陣列。 |
| GetValuesAsUnderlyingType<TEnum>() |
擷取指定列舉型別中基礎型別常數值的陣列。 |
| HasFlag(Enum) |
判斷目前實例中是否設定一或多個位欄位。 |
| IsDefined(Type, Object) |
傳回布爾值,指出指定的整數值或其名稱是否存在於指定的列舉中。 |
| IsDefined<TEnum>(TEnum) |
傳回布爾值,指出指定的整數值或其名稱是否存在於指定的列舉中。 |
| MemberwiseClone() |
建立目前 Object的淺層複本。 (繼承來源 Object) |
| Parse(Type, ReadOnlySpan<Char>, Boolean) |
將一或多個列舉常數之名稱或數值的字元表示範圍轉換為相等的列舉物件。 參數會指定作業是否不區分大小寫。 |
| Parse(Type, ReadOnlySpan<Char>) |
將一或多個列舉常數之名稱或數值的字元表示範圍轉換為相等的列舉物件。 |
| Parse(Type, String, Boolean) |
將一或多個列舉常數之名稱或數值的字串表示轉換為相等的列舉物件。 參數會指定作業是否不區分大小寫。 |
| Parse(Type, String) |
將一或多個列舉常數之名稱或數值的字串表示轉換為相等的列舉物件。 |
| Parse<TEnum>(ReadOnlySpan<Char>, Boolean) |
將 |
| Parse<TEnum>(ReadOnlySpan<Char>) |
將 |
| Parse<TEnum>(String, Boolean) |
將 |
| Parse<TEnum>(String) |
將 |
| ToObject(Type, Byte) |
將指定的 8 位無符號整數轉換為列舉成員。 |
| ToObject(Type, Int16) |
將指定的16位帶正負號整數轉換為列舉成員。 |
| ToObject(Type, Int32) |
將指定的32位帶正負號整數轉換為列舉成員。 |
| ToObject(Type, Int64) |
將指定的64位帶正負號整數轉換為列舉成員。 |
| ToObject(Type, Object) |
將具有整數值的指定物件轉換為列舉成員。 |
| ToObject(Type, SByte) |
將指定的8位帶正負號整數值轉換為列舉成員。 |
| ToObject(Type, UInt16) |
將指定的16位無符號整數值轉換為列舉成員。 |
| ToObject(Type, UInt32) |
將指定的32位無符號整數值轉換為列舉成員。 |
| ToObject(Type, UInt64) |
將指定的 64 位無符號整數值轉換為列舉成員。 |
| ToString() |
將這個實例的值轉換為其相等的字串表示。 |
| ToString(IFormatProvider) |
已淘汰.
已淘汰.
這個方法多載已經過時;使用 ToString()。 |
| ToString(String, IFormatProvider) |
已淘汰.
已淘汰.
這個方法多載已經過時;使用 ToString(String)。 |
| ToString(String) |
使用指定的格式,將這個實例的值轉換為其相等的字串表示。 |
| TryFormat<TEnum>(TEnum, Span<Char>, Int32, ReadOnlySpan<Char>) |
嘗試將列舉型別實例的值格式化為提供的字元範圍。 |
| TryParse(Type, ReadOnlySpan<Char>, Boolean, Object) |
將一或多個列舉常數之名稱或數值的字元表示範圍轉換為相等的列舉物件。 參數會指定作業是否不區分大小寫。 |
| TryParse(Type, ReadOnlySpan<Char>, Object) |
將一或多個列舉常數之名稱或數值的字元表示範圍轉換為相等的列舉物件。 |
| TryParse(Type, String, Boolean, Object) |
將一或多個列舉常數之名稱或數值的字串表示轉換為相等的列舉物件。 |
| TryParse(Type, String, Object) |
將一或多個列舉常數之名稱或數值的字串表示轉換為相等的列舉物件。 |
| TryParse<TEnum>(ReadOnlySpan<Char>, Boolean, TEnum) |
將一或多個列舉常數之名稱或數值的字串表示轉換為相等的列舉物件。 參數會指定作業是否區分大小寫。 傳回值表示轉換是否成功。 |
| TryParse<TEnum>(ReadOnlySpan<Char>, TEnum) |
將一或多個列舉常數之名稱或數值的字串表示轉換為相等的列舉物件。 |
| TryParse<TEnum>(String, Boolean, TEnum) |
將一或多個列舉常數之名稱或數值的字串表示轉換為相等的列舉物件。 參數會指定作業是否區分大小寫。 傳回值表示轉換是否成功。 |
| TryParse<TEnum>(String, TEnum) |
將一或多個列舉常數之名稱或數值的字串表示轉換為相等的列舉物件。 傳回值表示轉換是否成功。 |
明確介面實作
適用於
執行緒安全性
此類型是安全線程。