Partilhar via


Classe System.Enum

Este artigo fornece observações complementares à documentação de referência para esta API.

Uma enumeração é um conjunto de constantes nomeadas cujo tipo subjacente é qualquer tipo integral. Se nenhum tipo subjacente for explicitamente declarado, Int32 será usado. Enum é a classe base para todas as enumerações no .NET. Os tipos de enumeração são definidos pela palavra-chave enum em C#, a construção Enum...End Enum no Visual Basic e a palavra-chave type em F#.

Enum fornece métodos para comparar instâncias dessa classe, convertendo o valor de uma instância em sua representação de cadeia de caracteres, convertendo a representação de cadeia de caracteres de um número em uma instância dessa classe e criando uma instância de uma enumeração e valor especificados.

Você também pode tratar uma enumeração como um campo bit. Para mais informações, veja a seção Membros não exclusivos e as seções Atributo 'Flags' e FlagsAttribute.

Criar um tipo de enumeração

As linguagens de programação normalmente fornecem sintaxe para declarar uma enumeração que consiste em um conjunto de constantes nomeadas e seus valores. O exemplo a seguir ilustra a sintaxe usada por C#, F# e Visual Basic para definir uma enumeração. Ele cria uma enumeração chamada ArrivalStatus que tem três membros: ArrivalStatus.Early, ArrivalStatus.OnTimee ArrivalStatus.Late. Observe que, em todos os casos, a enumeração não herda explicitamente de Enum; A relação de herança é tratada implicitamente pelo compilador.

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

Advertência

Você nunca deve criar um tipo de enumeração cujo tipo subjacente seja não integral ou Char. Embora você possa criar esse tipo de enumeração usando reflexão, as chamadas de método que usam o tipo resultante não são confiáveis e também podem gerar exceções adicionais.

Instanciar um tipo de enumeração

Você pode instanciar um tipo de enumeração da mesma forma que instancia qualquer outro tipo de valor: declarando uma variável e atribuindo uma das constantes da enumeração a ela. O exemplo a seguir instancia um ArrivalStatus cujo valor é 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)

Você também pode instanciar um valor de enumeração das seguintes maneiras:

  • Usando os recursos de uma linguagem de programação específica para lançar (como em C#) ou converter (como no Visual Basic) um valor inteiro em um valor de enumeração. O exemplo a seguir cria um objeto ArrivalStatus cujo valor é ArrivalStatus.Early dessa maneira.

    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)
    
  • Chamando seu construtor implícito sem parâmetros. Como mostra o exemplo a seguir, nesse caso, o valor subjacente da instância de enumeração é 0. No entanto, este não é necessariamente o valor de uma constante válida na enumeração.

    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)
    
  • Chamando o método Parse ou TryParse para analisar uma cadeia de caracteres que contém o nome de uma constante na enumeração. Para obter mais informações, consulte a seção Analisar valores de enumeração.

  • Chamando o método ToObject para converter um valor integral em um tipo de enumeração. Para obter mais informações, consulte a secção Executar conversões.

Práticas recomendadas de enumeração

Recomendamos que você use as seguintes práticas recomendadas ao definir tipos de enumeração:

  • Se você não definiu um membro de enumeração cujo valor é 0, considere criar uma constante None enumerada. Por padrão, a memória usada para a enumeração é inicializada como zero pelo common language runtime. Consequentemente, se você não definir uma constante cujo valor é zero, a enumeração conterá um valor ilegal quando for criada.

  • Se houver um caso padrão óbvio que seu aplicativo tem que representar, considere usar uma constante enumerada cujo valor é zero para representá-lo. Se não houver nenhum caso padrão, considere usar uma constante enumerada cujo valor é zero para especificar o caso que não é representado por nenhuma das outras constantes enumeradas.

  • Não especifique constantes enumeradas que são reservadas para uso futuro.

  • Ao definir um método ou propriedade que usa uma constante enumerada como um valor, considere validar o valor. O motivo é que você pode converter um valor numérico para o tipo de enumeração, mesmo que esse valor numérico não esteja definido na enumeração.

Práticas recomendadas adicionais para tipos de enumeração cujas constantes são campos de bits estão listadas na seção Membros não exclusivos e no atributo Flags seção.

Executar operações com enumerações

Não é possível definir novos métodos quando você está criando uma enumeração. No entanto, um tipo de enumeração herda um conjunto completo de métodos estáticos e de instância da classe Enum. As seções a seguir examinam a maioria desses métodos, além de vários outros métodos que são comumente usados ao trabalhar com valores de enumeração.

Realizar conversões

Você pode converter entre um membro de enumeração e seu tipo subjacente usando um operador de casting (em C# e F#) ou de conversão (em Visual Basic). Em F#, a função enum também é usada. O exemplo a seguir usa operadores de conversão ou de coerção para executar conversões de um inteiro para um valor de enumeração e de um valor de enumeração para um inteiro.

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)

A classe Enum também inclui um método ToObject que converte um valor de qualquer tipo integral em um valor de enumeração. O exemplo a seguir usa o método ToObject(Type, Int32) para converter um Int32 em um valor ArrivalStatus. Observe que, uma vez que o ToObject retorna um valor do tipo Object, pode ainda ser necessário usar um operador de conversão para converter o objeto para o tipo de enumeração.

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)

Ao converter um inteiro em um valor de enumeração, é possível atribuir um valor que não é realmente um membro da enumeração. Para evitar isso, você pode passar o inteiro para o método IsDefined antes de executar a conversão. O exemplo a seguir usa esse método para determinar se os elementos em uma matriz de valores inteiros podem ser convertidos em valores 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

Embora a classe Enum forneça implementações de interface explícitas da interface IConvertible para conversão de um valor de enumeração para um tipo integral, você deve usar os métodos da classe Convert, como ToInt32, para executar essas conversões. O exemplo a seguir ilustra como você pode usar o método GetUnderlyingType junto com o método Convert.ChangeType para converter um valor de enumeração em seu tipo subjacente. Observe que este exemplo não requer que o tipo subjacente da enumeração seja conhecido em tempo de compilação.

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

Analisar valores de enumeração

Os métodos Parse e TryParse permitem converter a representação de cadeia de caracteres de um valor de enumeração para esse valor. A representação de cadeia de caracteres pode ser o nome ou o valor subjacente de uma constante de enumeração. Observe que os métodos de análise converterão com êxito representações de cadeia de caracteres de números que não são membros de uma enumeração específica se as cadeias de caracteres puderem ser convertidas em um valor do tipo subjacente da enumeração. Para evitar isso, o método IsDefined pode ser chamado para garantir que o resultado do método de análise seja um valor de enumeração válido. O exemplo ilustra essa abordagem e demonstra chamadas para os métodos Parse(Type, String) e Enum.TryParse<TEnum>(String, TEnum). Observe que o método de análise não genérico retorna um objeto que você pode ter que converter (em C# e F#) ou converter (em Visual Basic) para o tipo de enumeração apropriado.

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

Formatar valores de enumeração

Você pode converter valores de enumeração nas suas representações em cadeia de caracteres chamando o método estático Format, bem como as sobrecargas do método de instância ToString. Você pode usar uma cadeia de caracteres de formato para controlar a maneira precisa na qual um valor de enumeração é representado como uma cadeia de caracteres. Para obter mais informações, consulte Enumeration Format Strings. O exemplo a seguir usa cada uma das cadeias de caracteres de formato de enumeração suportadas ("G" ou "g", "D" ou "d", "X" ou "x" e "F" ou "f" ) para converter um membro da enumeração ArrivalStatus em suas representações de cadeia de caracteres.

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

Percorrer elementos de enumeração

O tipo Enum não implementa a interface IEnumerable ou IEnumerable<T>, o que permitiria iterar membros de uma coleção usando uma construção foreach (em C#), for..in (em F#) ou For Each (em Visual Basic). No entanto, você pode enumerar membros de duas maneiras.

  • Você pode chamar o método GetNames para recuperar uma matriz de cadeia de caracteres contendo os nomes dos membros da enumeração. Em seguida, para cada elemento da matriz de cadeia de caracteres, você pode chamar o método Parse para converter a cadeia de caracteres em seu valor de enumeração equivalente. O exemplo a seguir ilustra essa abordagem.

    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)
    
  • Você pode chamar o método GetValues para recuperar uma matriz que contém os valores subjacentes na enumeração. Em seguida, para cada elemento da matriz, você pode chamar o método ToObject para converter o inteiro em seu valor de enumeração equivalente. O exemplo a seguir ilustra essa abordagem.

    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)
    

Membros não exclusivos e o atributo Flags

Um uso comum de uma enumeração é representar um conjunto de valores mutuamente exclusivos. Por exemplo, uma instância ArrivalStatus pode ter um valor de Early, OnTimeou Late. Não faz sentido que o valor de uma instância ArrivalStatus reflita mais de uma constante de enumeração.

Em outros casos, no entanto, o valor de um objeto de enumeração pode incluir vários membros de enumeração, e cada membro representa um campo de bit no valor de enumeração. O atributo FlagsAttribute pode ser usado para indicar que a enumeração consiste em campos de bits. Por exemplo, uma enumeração chamada Pets pode ser usada para indicar os tipos de animais de estimação em uma casa. Pode definir-se da seguinte forma.

[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

A enumeração Pets pode ser usada como mostrado no exemplo a seguir.

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)

As práticas recomendadas a seguir devem ser usadas ao definir uma enumeração bit a bit e aplicar o atributo FlagsAttribute.

  • Use o atributo personalizado FlagsAttribute para uma enumeração somente se uma operação bit a bit (AND, OR, EXCLUSIVE OR) deve ser executada em um valor numérico.

  • Defina constantes de enumeração em potências de dois, ou seja, 1, 2, 4, 8 e assim por diante. Isso significa que os sinalizadores individuais em constantes de enumeração combinadas não se sobrepõem.

  • Considere a criação de uma constante enumerada para combinações de sinalizadores comumente usadas. Por exemplo, se você tiver uma enumeração usada para operações de E/S de arquivo que contenha as constantes enumeradas Read = 1 e Write = 2, considere criar a constante enumerada ReadWrite = Read OR Write, que combina os sinalizadores Read e Write. Além disso, a operação OR bit a bit usada para combinar os sinalizadores pode ser considerada um conceito avançado em algumas circunstâncias, não devendo ser necessário para tarefas simples.

  • Tenha cuidado se definir um número negativo como uma constante enumerada de sinalizador, pois muitas posições de sinalizador podem ser definidas como 1, o que pode tornar seu código confuso e incentivar erros de codificação.

  • Uma maneira conveniente de testar se um sinalizador está definido em um valor numérico é chamar a instância HasFlag método, conforme mostrado no exemplo a seguir.

    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.
    

    É equivalente a executar uma operação AND bit a bit entre o valor numérico e a constante enumerada do sinalizador, que define todos os bits no valor numérico como zero que não correspondem ao sinalizador e, em seguida, testar se o resultado dessa operação é igual à constante enumerada do sinalizador. Isso é ilustrado no exemplo a seguir.

    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.
    
  • Use None como o nome da constante enumerada do sinalizador cujo valor é zero. Não é possível usar a constante enumerada None em uma operação bit a bit AND para testar um sinalizador porque o resultado é sempre zero. No entanto, você pode executar uma comparação lógica, não bitwise, entre o valor numérico e a constante None enumerada para determinar se algum bit no valor numérico está definido. Isso é ilustrado no exemplo a seguir.

    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.
    
  • Não defina um valor de enumeração apenas para espelhar o estado da própria enumeração. Por exemplo, não defina uma constante enumerada que apenas marque o final da enumeração. Se você precisar determinar o último valor da enumeração, verifique esse valor explicitamente. Além disso, você pode executar uma verificação de intervalo para a primeira e a última constante enumerada se todos os valores dentro do intervalo forem válidos.

Adicionar métodos de enumeração

Como os tipos de enumeração são definidos por estruturas de linguagem, como enum (C#) e Enum (Visual Basic), você não pode definir métodos personalizados para um tipo de enumeração diferente desses métodos herdados da classe Enum. No entanto, você pode usar métodos de extensão para adicionar funcionalidade a um tipo de enumeração específico.

No exemplo a seguir, a enumeração Grades representa as possíveis notas por letras que um aluno pode receber numa disciplina. Um método de extensão chamado Passing é adicionado ao tipo Grades para que cada instância desse tipo agora "saiba" se representa uma nota de aprovação ou não. A classe Extensions também contém uma variável estática de leitura-gravação que define a nota mínima de aprovação. O valor de retorno do método de extensão Passing reflete o valor atual dessa variável.

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 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.

Exemplos

O exemplo a seguir demonstra o uso de uma enumeração para representar valores nomeados e outra enumeração para representar campos de bit nomeados.

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