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 提供了用于比较此类实例的方法,将实例的值转换为其字符串表示形式,将数字的字符串表示形式转换为此类的实例,以及创建指定枚举和值的实例。
你还可以将枚举视为位域。 有关详细信息,请参阅 “非独占成员”和“标志”属性 部分和 FlagsAttribute。
创建枚举类型
编程语言通常提供语法来声明一个由一组命名常量及其值组成的枚举。 以下示例说明了 C#、F# 和 Visual Basic 用于定义枚举的语法。 它创建一个名为具有 ArrivalStatus 三个成员的枚举: ArrivalStatus.Early、 ArrivalStatus.OnTime和 ArrivalStatus.Late。 请注意,在所有情形下,枚举不会显式地继承< c0 />,继承关系由编译器隐式处理。
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枚举常量。 默认情况下,用于枚举的内存由公共语言运行时初始化为零。 因此,如果未定义值为零的常量,则枚举将在创建时包含非法值。如果应用程序必须表示一个明显的默认情况,请考虑使用枚举常量,其值为零来表示它。 如果没有默认情况,请考虑使用值为零的枚举常量来指定其他任何枚举常量未表示的情况。
请勿指定为将来使用保留的枚举常量。
定义将枚举常量作为值的方法或属性时,请考虑验证该值。 原因是,即使数值未在枚举中定义,仍然可以将数值转换为枚举类型。
有关常量是位字段的枚举类型的其他最佳做法,请参阅 “非独占成员”和“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)
非独占成员和 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: {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 属性时,应使用以下最佳做法。
FlagsAttribute仅当对数值执行按位运算(AND、OR、EXCLUSIVE OR)时,才对枚举使用自定义属性。
以 2 的幂来定义枚举常量,即 1、2、4、8 等。 这意味着组合枚举常量中的单个标志不会重叠。
请考虑为常用标志组合创建枚举常量。 例如,如果你有一个用于文件 I/O操作的枚举,其中包含枚举常量
Read = 1和Write = 2,请考虑创建枚举常量ReadWrite = Read OR Write,该常量合并了Read和Write标志。 此外,用于组合标志的按位或运算在某些情况下可能被视为高级概念,而简单任务则不需要它。如果将负数定义为标志枚举常量,请谨慎,因为许多标志位可能会被设置为 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.它等效于对数值和标志枚举常量执行按位与运算,将数值中与标志不对应的所有位设置为零,然后测试该运算结果是否等于标志枚举常量。 下列示例对此进行了阐释。
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.
构造函数
| 名称 | 说明 |
|---|---|
| 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>, 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) |
将一个或多个枚举常量的名称或数值的名称或数值的字符串表示形式转换为等效的枚举对象。 返回值指示转换是否成功。 |
显式接口实现
适用于
线程安全性
此类型是线程安全的。