Compartilhar via


19 enumerações

19.1 Geral

Um tipo de enumeração é um tipo de valor distinto (§8.3) que declara um conjunto de constantes nomeadas.

Exemplo: O exemplo

enum Color
{
    Red,
    Green,
    Blue
}

declara um tipo de enumeração chamado Color com membros Red, Greene Blue.

exemplo de fim

19.2 Declarações de enumeração

Uma declaração de enumeração declara um novo tipo de enumeração. Uma declaração de enumeração começa com a palavra-chave enume define o nome, a acessibilidade, o tipo subjacente e os membros da enumeração.

enum_declaration
    : attributes? enum_modifier* 'enum' identifier enum_base? enum_body ';'?
    ;

enum_base
    : ':' integral_type
    | ':' integral_type_name
    ;

integral_type_name
    : type_name // Shall resolve to an integral type other than char
    ;

enum_body
    : '{' enum_member_declarations? '}'
    | '{' enum_member_declarations ',' '}'
    ;

Cada tipo de enumeração tem um tipo integral correspondente chamado de tipo subjacente do tipo de enumeração. Esse tipo subjacente deve ser capaz de representar todos os valores do enumerador definidos na enumeração. Se o enum_base estiver presente, ele declarará explicitamente o tipo subjacente. O tipo subjacente deve ser um dos tipos integrais (§8.3.6) diferente de char. O tipo subjacente pode ser especificado por um integral_type (§8.3.5) ou um integral_type_name. O integral_type_name é resolvido da mesma forma que type_name (§7.8.1), incluindo a consideração de quaisquer diretivas de uso (§14.5).

Observação: o char tipo não pode ser usado como um tipo subjacente, seja por palavra-chave ou por meio de um integral_type_namearquivo . nota final

Uma declaração de enumeração que não declara explicitamente um tipo subjacente tem um tipo subjacente de int.

Exemplo: O exemplo

enum Color : long
{
    Red,
    Green,
    Blue
}

declara uma enumeração com um tipo subjacente de long.

exemplo de fim

Nota: Um desenvolvedor pode optar por usar um tipo subjacente de long, como no exemplo, para habilitar o uso de valores que estão no intervalo de long , mas não no intervalo de int, ou para preservar essa opção para o futuro. nota final

Observação: o C# permite uma vírgula à direita em um enum_body, assim como permite uma em um array_initializer (§17.7). nota final

Uma declaração de enumeração não pode incluir uma lista de parâmetros de tipo, mas qualquer enumeração aninhada dentro de uma declaração de classe genérica ou uma declaração de struct genérica é uma declaração de enumeração genérica, pois os argumentos de tipo para o tipo que contém devem ser fornecidos para criar um tipo construído (§8.4).

19.3 Modificadores de enumeração

Um enum_declaration pode incluir opcionalmente uma sequência de modificadores de enumeração:

enum_modifier
    : 'new'
    | 'public'
    | 'protected'
    | 'internal'
    | 'private'
    ;

É um erro de tempo de compilação para o mesmo modificador aparecer várias vezes em uma declaração de enumeração.

Os modificadores de uma declaração de enumeração têm o mesmo significado que os de uma declaração de classe (§15.2.2). No entanto, os abstractmodificadores , e sealed, e static não são permitidos em uma declaração de enumeração. As enumerações não podem ser abstratas e não permitem derivação.

19.4 Membros da enumeração

O corpo de uma declaração de tipo de enumeração define zero ou mais membros de enumeração, que são as constantes nomeadas do tipo de enumeração. Dois membros enumerados não podem ter o mesmo nome.

enum_member_declarations
    : enum_member_declaration (',' enum_member_declaration)*
    ;
enum_member_declaration
    : attributes? identifier ('=' constant_expression)?
    ;

Cada membro de enumeração tem um valor constante associado. O tipo desse valor é o tipo subjacente para a enumeração que o contém. O valor constante para cada membro de enumeração deve estar no intervalo do tipo subjacente para a enumeração.

Exemplo: O exemplo

enum Color: uint
{
    Red = -1,
    Green = -2,
    Blue = -3
}

resulta em um erro de tempo de compilação porque os valores -1constantes , -2, e -3 não estão no intervalo do tipo uintintegral subjacente .

exemplo de fim

Vários membros de enumeração podem compartilhar o mesmo valor associado.

Exemplo: O exemplo

enum Color
{
    Red,
    Green,
    Blue,
    Max = Blue
}

mostra uma enumeração na qual dois membros da enumeração —Blue e Max—têm o mesmo valor associado.

exemplo de fim

O valor associado de um membro de enumeração é atribuído implícita ou explicitamente. Se a declaração do membro de enumeração tiver um inicializador constant_expression , o valor dessa expressão constante, implicitamente convertido no tipo subjacente da enumeração, será o valor associado do membro de enumeração. Se a declaração do membro de enumeração não tiver nenhum inicializador, seu valor associado será definido implicitamente, da seguinte maneira:

  • Se o membro de enumeração for o primeiro membro de enumeração declarado no tipo de enumeração, seu valor associado será zero.
  • Caso contrário, o valor associado do membro de enumeração é obtido aumentando o valor associado do membro de enumeração textualmente anterior em um. Esse valor aumentado deve estar dentro do intervalo de valores que podem ser representados pelo tipo subjacente, caso contrário, ocorrerá um erro em tempo de compilação.

Exemplo: O exemplo

enum Color
{
    Red,
    Green = 10,
    Blue
}

class Test
{
    static void Main()
    {
        Console.WriteLine(StringFromColor(Color.Red));
        Console.WriteLine(StringFromColor(Color.Green));
        Console.WriteLine(StringFromColor(Color.Blue));
    }

    static string StringFromColor(Color c)
    {
        switch (c)
        {
            case Color.Red:
                return $"Red = {(int) c}";
            case Color.Green:
                return $"Green = {(int) c}";
            case Color.Blue:
                return $"Blue = {(int) c}";
            default:
                return "Invalid color";
      }
   }
}

imprime os nomes dos membros da enumeração e seus valores associados. A saída é:

Red = 0
Green = 10
Blue = 11

pelos seguintes motivos:

  • O membro Red de enumeração recebe automaticamente o valor zero (já que ele não tem inicializador e é o primeiro membro de enumeração);
  • o membro Green enumeração recebe explicitamente o valor 10;
  • e o membro Blue de enumeração recebe automaticamente o valor um maior que o membro que o precede textualmente.

exemplo de fim

O valor associado de um membro enumerado não deve, direta ou indiretamente, usar o valor de seu próprio membro enumerado associado. Além dessa restrição de circularidade, os inicializadores de membro de enumeração podem se referir livremente a outros inicializadores de membro de enumeração, independentemente de sua posição textual. Em um inicializador de membro de enumeração, os valores de outros membros de enumeração são sempre tratados como tendo o tipo de seu tipo subjacente, de modo que as conversões não sejam necessárias ao se referir a outros membros de enumeração.

Exemplo: O exemplo

enum Circular
{
    A = B,
    B
}

resulta em um erro de tempo de compilação porque as declarações de A e B são circulares. A depende explicitamente B e B depende implicitamente A .

exemplo de fim

Os membros de enumeração são nomeados e definidos de maneira exatamente análoga aos campos dentro das classes. O escopo de um membro enumeração é o corpo de seu tipo de enumeração que o contém. Dentro desse escopo, os membros da enumeração podem ser referidos por seu nome simples. De todos os outros códigos, o nome de um membro de enumeração deve ser qualificado com o nome de seu tipo de enumeração. Os membros de enumeração não têm nenhuma acessibilidade declarada — um membro de enumeração estará acessível se o tipo de enumeração que o contém estiver acessível.

19.5 O tipo System.Enum

O tipo System.Enum é a classe base abstrata de todos os tipos de enumeração (isso é distinto e diferente do tipo subjacente do tipo de enumeração) e os membros herdados de estão disponíveis em qualquer tipo de System.Enum enumeração. Existe uma conversão de boxing (§10.2.9) de qualquer tipo de enumeração para System.Enum, e uma conversão de unboxing (§10.3.7) existe de para qualquer tipo de System.Enum enumeração.

Observe que System.Enum isso não é em si um enum_type. Em vez disso, é um class_type do qual todos os enum_typesão derivados. O tipo System.Enum herda do tipo System.ValueType (§8.3.2), que, por sua vez, herda do tipo object. Em tempo de execução, um valor do tipo System.Enum pode ser null ou uma referência a um valor em caixa de qualquer tipo de enumeração.

19.6 Valores e operações de enumeração

Cada tipo de enumeração define um tipo distinto; Uma conversão de enumeração explícita (§10.3.3) é necessária para converter entre um tipo de enumeração e um tipo integral ou entre dois tipos de enumeração. O conjunto de valores do tipo enumeração é o mesmo que o conjunto de valores do tipo subjacente e não está restrito aos valores das constantes nomeadas. Qualquer valor do tipo subjacente de uma enumeração pode ser convertido no tipo de enumeração e é um valor válido distinto desse tipo de enumeração.

Os membros de enumeração têm o tipo de enumeração que o contém (exceto em outros inicializadores de membro de enumeração: consulte §19.4). O valor de um membro de enumeração declarado no tipo E de enumeração com valor v associado é (E)v.

Os seguintes operadores podem ser usados em valores de tipos de enumeração:

Cada tipo de enumeração deriva automaticamente da classe System.Enum (que, por sua vez, deriva de System.ValueType e object). Assim, métodos e propriedades herdados dessa classe podem ser usados em valores de um tipo de enumeração.