Enum Класс
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Предоставляет базовый класс для перечислений.
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
конструкцией ...End Enum
в Visual Basic и ключевым словом 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)
Вызывая или TryParse метод Parse для синтаксического анализа строки, содержащей имя константы в перечислении. Дополнительные сведения см. в разделе "Анализ значений перечисления ".
Вызывая ToObject метод для преобразования целочисленного значения в тип перечисления. Дополнительные сведения см. в разделе "Выполнение преобразований ".
Рекомендации по перечислению
При определении типов перечисления рекомендуется использовать следующие рекомендации.
Если элемент перечисления не определен, значение которого равно 0, рассмотрите возможность создания перечислимой
None
константы. По умолчанию память, используемая для перечисления, инициализируется до нуля средой CLR. Следовательно, если не определить константу, значение которой равно нулю, перечисление будет содержать недопустимое значение при его создании.Если имеется очевидный вариант по умолчанию, который должен представлять приложение, рассмотрите возможность использования перечисляемой константы, значение которой равно нулю для представления. Если нет регистра по умолчанию, рассмотрите возможность использования перечисляемой константы, значение которой равно нулю, чтобы указать регистр, который не представлен ни одной из других перечисленных констант.
Не указывайте перечисляемые константы, зарезервированные для использования в будущем.
При определении метода или свойства, принимающего перечислимую константу в качестве значения, рассмотрите возможность проверки значения. Причина в том, что числовое значение можно привести к типу перечисления, даже если это числовое значение не определено в перечислении.
Дополнительные рекомендации по типам перечисления, константы которых являются битовыми полями, перечислены в разделе "Неисключающие члены" и "Атрибут флагов ".
Выполнение операций с перечислениями
При создании перечисления нельзя определить новые методы. Однако тип перечисления наследует полный набор статических и экземплярных методов от 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) для преобразования в 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 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 что результат метода синтаксического анализа является допустимым значением перечисления. Пример иллюстрирует этот подход и демонстрирует вызовы как методов, так 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 '{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#), (в F#) for..in
или 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) должна выполняться с числовым значением.
Определите константы перечисления в силах двух, то есть 1, 2, 4, 8 и т. д. Это означает, что отдельные флаги в объединенных константы перечисления не перекрываются.
Рассмотрите возможность создания перечислимой константы для часто используемых сочетаний флагов. Например, если у вас есть перечисление, используемое для операций ввода-вывода файлов, содержащих перечислимые константы, и
Write = 2
рассмотрите возможность создания перечислимой константыRead = 1
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
в качестве имени перечисляемой константы флага, значение которой равно нулю. ПеречислимуюNone
константу нельзя использовать в побитовой операции AND для проверки флага, так как результат всегда равен нулю. Однако можно выполнить логическое, а не побитовое, сравнение между числовым значением и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>() |
Возвращает массив значений констант в указанном типе перечисления. |
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) |
Преобразует строковое представление имени или числового значения одной или нескольких перечислимых констант в эквивалентный перечислимый объект. Возвращаемое значение указывает, успешно ли выполнено преобразование. |
Явные реализации интерфейса
IConvertible.GetTypeCode() |
Возвращает код типа этого экземпляра Enum. |
IConvertible.ToBoolean(IFormatProvider) |
Преобразует текущее значение в логическое значение на основе его базового типа. |
IConvertible.ToByte(IFormatProvider) |
Преобразует текущее значение в 8-битовое целое число без знака на основе базового типа. |
IConvertible.ToChar(IFormatProvider) |
Преобразует текущее значение в символ Юникода на основе его базового типа. |
IConvertible.ToDateTime(IFormatProvider) |
Преобразует текущее значение в значение типа DateTime на основе его базового типа. |
IConvertible.ToDecimal(IFormatProvider) |
Преобразует текущее значение в значение типа Decimal на основе его базового типа. |
IConvertible.ToDouble(IFormatProvider) |
Преобразует текущее значение объекта в число двойной точности с плавающей запятой на основе его базового типа. |
IConvertible.ToInt16(IFormatProvider) |
Преобразует текущее значение в 16-битовое целое число со знаком на основе его базового типа. |
IConvertible.ToInt32(IFormatProvider) |
Преобразует текущее значение в 32-битовое целое число со знаком на основе его базового типа. |
IConvertible.ToInt64(IFormatProvider) |
Преобразует текущее значение в 64-битовое целое число со знаком на основе его базового типа. |
IConvertible.ToSByte(IFormatProvider) |
Преобразует текущее значение в 8-битовое целое число со знаком на основе его базового типа. |
IConvertible.ToSingle(IFormatProvider) |
Преобразует текущее значение в число с плавающей запятой одиночной точности на основе его базового типа. |
IConvertible.ToString(IFormatProvider) |
Является устаревшей.
Эта перегрузка метода является устаревшей, используйте вместо нее ToString(). |
IConvertible.ToType(Type, IFormatProvider) |
Преобразует текущее значение к заданному типу на основе его базового типа. |
IConvertible.ToUInt16(IFormatProvider) |
Преобразует текущее значение в 16-битовое целое число без знака на основе его базового типа. |
IConvertible.ToUInt32(IFormatProvider) |
Преобразует текущее значение в 32-битовое целое число без знака на основе его базового типа. |
IConvertible.ToUInt64(IFormatProvider) |
Преобразует текущее значение в 64-битовое целое число без знака на основе его базового типа. |
IFormattable.ToString(String, IFormatProvider) |
Является устаревшей.
Эта перегрузка метода является устаревшей. Используйте ToString(String). |
Применяется к
Потокобезопасность
Данный тип потокобезопасен.