Enum 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
提供列舉的基底類別。
public ref class Enum abstract : ValueType, IComparable, IConvertible, IFormattable
public ref class Enum abstract : ValueType, IComparable, IFormattable
public abstract class Enum : ValueType, IComparable, IConvertible, IFormattable
[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
[<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, IFormattable
- 繼承
- 衍生
- 屬性
- 實作
範例
下列範例示範如何使用列舉來表示具名值,以及另一個列舉來代表具名位欄位。
using namespace System;
enum class Days
{
Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday
};
enum class BoilingPoints
{
Celsius = 100,
Fahrenheit = 212
};
[Flags]
enum class Colors
{
Red = 1,
Green = 2,
Blue = 4,
Yellow = 8
};
int main()
{
Type^ weekdays = Days::typeid;
Type^ boiling = BoilingPoints::typeid;
Console::WriteLine( "The days of the week, and their corresponding values in the Days Enum are:" );
Array^ a = Enum::GetNames( weekdays );
Int32 i = 0;
do
{
Object^ o = a->GetValue( i );
Console::WriteLine( "{0,-11}= {1}", o->ToString(), Enum::Format( weekdays, Enum::Parse( weekdays, o->ToString() ), "d" ) );
}
while ( ++i < a->Length );
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:" );
i = 0;
Array^ b = Enum::GetNames( boiling );
do
{
Object^ o = b->GetValue( i );
Console::WriteLine( "{0,-11}= {1}", o->ToString(), Enum::Format( boiling, Enum::Parse( boiling, o->ToString() ), "d" ) );
}
while ( ++i < b->Length );
Array^ c = Enum::GetNames( Colors::typeid );
Colors myColors = Colors::Red | Colors::Blue | Colors::Yellow;
Console::WriteLine();
Console::Write( "myColors holds a combination of colors. Namely:" );
for ( i = 0; i < 3; i++ )
Console::Write( " {0}", c->GetValue( i ) );
}
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: {0}", 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 Framework中所有列舉的基類。 列舉型別是由 enum
C# Enum
中的 關鍵字、Visual Basic 中的 ... End Enum
建構和 type
F# 中的 關鍵字所定義。
Enum 提供比較這個類別實例的方法、將實例的值轉換成其字串表示、將數位的字串表示轉換成這個類別的實例,以及建立指定列舉和值的實例。
您也可以將列舉視為位欄位。 如需詳細資訊,請參閱 非獨佔成員和旗標屬性 一節和 FlagsAttribute 主題。
本主題內容:
建立列舉型別具現化列舉型別 列舉型別的最佳做法使用列舉執行作業執行轉換剖析列舉值 格式化列舉值逐一查看列舉成員非獨佔成員和 Flags 屬性新增列舉方法
建立列舉型別
程式設計語言通常會提供語法來宣告列舉,其中包含一組具名常數及其值。 下列範例說明 C#、F# 和 Visual Basic 用來定義列舉的語法。 它會建立名為 ArrivalStatus
的列舉,其具有三個成員: ArrivalStatus.Early
、 ArrivalStatus.OnTime
和 ArrivalStatus.Late
。 請注意,在所有情況下,列舉不會明確繼承自 Enum ;繼承關聯性是由編譯器隱含處理。
public enum ArrivalStatus { Late=-1, OnTime=0, Early=1 };
type ArrivalStatus =
| Late = -1
| OnTime = 0
| Early = 1
Public Enum ArrivalStatus As Integer
Late = -1
OnTime = 0
Early = 1
End Enum
警告
您不應該建立基礎類型為非整數或 的列舉型別 Char 。 雖然您可以使用反映來建立這類列舉型別,但使用結果型別的方法呼叫並不可靠,也可能擲回其他例外狀況。
具現化列舉型別
您可以宣告變數,並將其中一個列舉常數指派給它,以具現化列舉類型,就像具現化任何其他實數值型別一樣。 下列範例會具現化 ArrivalStatus
其值為 ArrivalStatus.OnTime
的 。
public class Example
{
public static void Main()
{
ArrivalStatus status = ArrivalStatus.OnTime;
Console.WriteLine("Arrival Status: {0} ({0:D})", status);
}
}
// 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 Example
Public Sub Main()
Dim status As ArrivalStatus = ArrivalStatus.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: {0} ({0:D})", status2); // 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 ArrivalStatus = CType(1, ArrivalStatus) 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: {0} ({0:D})", status1); // 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 ArrivalStatus() 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 初始化為零。 因此,如果您未定義其值為零的常數,則列舉會在建立時包含不合法的值。如果您的應用程式必須表示明顯的預設案例,請考慮使用列舉常數,其值為零來表示它。 如果沒有預設案例,請考慮使用列舉常數,其值為零來指定任何其他列舉常數未表示的案例。
請勿指定保留供日後使用的列舉常數。
當您定義接受列舉常數做為值的方法或屬性時,請考慮驗證值。 原因是即使列舉中未定義數值,您也可以將數值轉換成列舉類型。
列舉型別的其他最佳做法,其常數是位欄位,列在 [非獨佔成員] 和 [旗標屬性] 區 段中。
使用列舉執行作業
當您建立列舉時,無法定義新的方法。 不過,列舉型別會從 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 ArrivalStatus = CType(value3, ArrivalStatus)
Dim value4 As Integer = CInt(status3)
類別 Enum 也包含 ToObject 方法,可將任何整數型別的值轉換為列舉值。 下列範例會 ToObject(Type, Int32) 使用 方法將 轉換為 Int32ArrivalStatus
值。 請注意,因為 會 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 ArrivalStatus = CType(ArrivalStatus.ToObject(GetType(ArrivalStatus), number), ArrivalStatus)
將整數轉換成列舉值時,可以指派不是列舉成員的值。 若要避免這種情況,您可以先將整數傳遞至 IsDefined 方法,再執行轉換。 下列範例會使用這個方法來判斷整數值陣列中的專案是否可以轉換成 ArrivalStatus
值。
using System;
public enum ArrivalStatus { Unknown=-3, Late=-1, OnTime=0, Early=1 };
public class Example
{
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 {0:N0} to {1}", value, 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 ArrivalStatus As Integer
Unknown = -3
Late = -1
OnTime = 0
Early = 1
End Enum
Module Example
Public Sub Main()
Dim values() As Integer = { -3, -1, 0, 1, 5, Int32.MaxValue }
For Each value In values
Dim status As ArrivalStatus
If [Enum].IsDefined(GetType(ArrivalStatus), value)
status = CType(value, ArrivalStatus)
Else
status = ArrivalStatus.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 {0} to {1}", status, 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 ArrivalStatus = ArrivalStatus.Early
Dim number = Convert.ChangeType(status, [Enum].GetUnderlyingType(GetType(ArrivalStatus)))
Console.WriteLine("Converted {0} to {1}", status, number)
' The example displays the following output:
' Converted Early to 1
剖析列舉值
Parse和 TryParse 方法可讓您將列舉值的字串表示轉換為該值。 字串表示可以是列舉常數的名稱或基礎值。 請注意,如果字串可以轉換成列舉基礎類型的值,剖析方法就會成功轉換不是特定列舉成員之數位的字串表示。 若要避免這種情況, IsDefined 可以呼叫 方法,以確保剖析方法的結果是有效的列舉值。 此範例說明此方法,並示範對 和 Enum.TryParse<TEnum>(String, TEnum) 方法的 Parse(Type, String) 呼叫。 請注意,非泛型剖析方法會傳回物件,您可能必須以 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 '{0}' to {1}", number, status1);
}
catch (FormatException) {
Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus value.",
number);
}
ArrivalStatus status2;
if (Enum.TryParse<ArrivalStatus>(name, out status2)) {
if (!(Enum.IsDefined(typeof(ArrivalStatus), status2)))
status2 = ArrivalStatus.Unknown;
Console.WriteLine("Converted '{0}' to {1}", name, status2);
}
else {
Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus value.",
number);
}
// 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 ArrivalStatus = CType([Enum].Parse(GetType(ArrivalStatus), number), ArrivalStatus)
If Not [Enum].IsDefined(GetType(ArrivalStatus), status1) Then status1 = ArrivalStatus.Unknown
Console.WriteLine("Converted '{0}' to {1}", number, status1)
Catch e As FormatException
Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus value.",
number)
End Try
Dim status2 As ArrivalStatus
If [Enum].TryParse(Of ArrivalStatus)(name, status2) Then
If Not [Enum].IsDefined(GetType(ArrivalStatus), status2) Then status2 = ArrivalStatus.Unknown
Console.WriteLine("Converted '{0}' to {1}", name, status2)
Else
Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus 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 ArrivalStatus = ArrivalStatus.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 {0}:", typeof(ArrivalStatus).Name); Array.Sort(names); foreach (var name in names) { ArrivalStatus status = (ArrivalStatus) Enum.Parse(typeof(ArrivalStatus), name); Console.WriteLine(" {0} ({0:D})", status); } // 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(ArrivalStatus)) Console.WriteLine("Members of {0}:", GetType(ArrivalStatus).Name) Array.Sort(names) For Each name In names Dim status As ArrivalStatus = CType([Enum].Parse(GetType(ArrivalStatus), name), ArrivalStatus) Console.WriteLine(" {0} ({0:D})", status) Next ' The example displays the following output: ' Members of ArrivalStatus: ' Early (1) ' Late (-1) ' OnTime (0) ' Unknown (-3)
您可以呼叫 GetValues 方法來擷取包含列舉中基礎值的陣列。 接下來,針對陣列的每個元素,您可以呼叫 ToObject 方法,將整數轉換為它的對等列舉值。 下列範例將示範這個方法。
var values = Enum.GetValues(typeof(ArrivalStatus)); Console.WriteLine("Members of {0}:", typeof(ArrivalStatus).Name); foreach (ArrivalStatus status in values) { Console.WriteLine(" {0} ({0:D})", status); } // 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(ArrivalStatus)) Console.WriteLine("Members of {0}:", GetType(ArrivalStatus).Name) For Each value In values Dim status As ArrivalStatus = CType([Enum].ToObject(GetType(ArrivalStatus), value), ArrivalStatus) Console.WriteLine(" {0} ({0:D})", status) Next ' The example displays the following output: ' Members of ArrivalStatus: ' OnTime (0) ' Early (1) ' Unknown (-3) ' Late (-1)
非獨佔成員和 Flags 屬性
列舉的其中一個常見用法是表示一組互斥值。 例如, 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: {0:G} ({0:D})", familyPets);
// 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 屬性時,應該使用下列最佳做法。
FlagsAttribute只有當位運算 (AND、OR、EXCLUSIVE OR、EXCLUSIVE OR) 是在數值上執行時,才使用列舉的自訂屬性。
定義兩個乘冪的列舉常數,也就是 1、2、4、8 等等。 這表示合併列舉常數中的個別旗標不會重迭。
請考慮為常用的旗標組合建立列舉常數。 例如,如果您有列舉型別用於包含列舉常數
Read = 1
和Write = 2
的檔案 I/O 作業,請考慮建立列舉常數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 Example
{
static void Main()
{
Grades g1 = Grades.D;
Grades g2 = Grades.F;
Console.WriteLine("{0} {1} a passing grade.", g1, g1.Passing() ? "is" : "is not");
Console.WriteLine("{0} {1} a passing grade.", g2, g2.Passing() ? "is" : "is not");
Extensions.minPassing = Grades.C;
Console.WriteLine("\nRaising the bar!\n");
Console.WriteLine("{0} {1} a passing grade.", g1, g1.Passing() ? "is" : "is not");
Console.WriteLine("{0} {1} a passing grade.", g2, g2.Passing() ? "is" : "is not");
}
}
// 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.
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 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.
建構函式
Enum() |
初始化 Enum 類別的新執行個體。 |
方法
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>) |
將一或多個列舉常數之名稱或數值的字元表示範圍轉換為相等的列舉物件。 |
Parse(Type, ReadOnlySpan<Char>, Boolean) |
將一或多個列舉常數之名稱或數值的字元表示範圍轉換為相等的列舉物件。 參數會定義運算是否區分大小寫。 |
Parse(Type, String) |
把一或多個列舉常數的名稱或數值的字串表示轉換為一個相等列舉物件。 |
Parse(Type, String, Boolean) |
把一或多個列舉常數的名稱或數值的字串表示轉換為一個相等列舉物件。 參數會定義運算是否區分大小寫。 |
Parse<TEnum>(ReadOnlySpan<Char>) |
將 所指定 |
Parse<TEnum>(ReadOnlySpan<Char>, Boolean) |
將 所指定 |
Parse<TEnum>(String) |
將一或多個列舉常數的名稱或數值字串表示 (由 |
Parse<TEnum>(String, Boolean) |
將一或多個列舉常數的名稱或數值字串表示 (由 |
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) |
使用指定格式,將這個執行個體的值轉換為它的相等字串表示。 |
ToString(String, IFormatProvider) |
已過時。
已過時。
這個方法多載已淘汰,請改用 ToString(String)。 |
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) |
把一或多個列舉常數的名稱或數值的字串表示轉換為一個相等列舉物件。 指出轉換是否成功的傳回值。 |
明確介面實作
適用於
執行緒安全性
此型別具備執行緒安全。