Compartir a través de


19 Enumeraciones

19.1 General

Un tipo de enumeración es un tipo de valor distinto (§8.3) que declara un conjunto de constantes con nombre.

Ejemplo: El ejemplo

enum Color
{
    Red,
    Green,
    Blue
}

declara un tipo de enumeración denominado Color con miembros Red, Greeny Blue.

ejemplo final

19.2 Declaraciones de enumeración

Una declaración de enumeración declara un nuevo tipo de enumeración. Una declaración de enumeración comienza con la palabra clave enumy define el nombre, la accesibilidad, el tipo subyacente y los miembros de la enumeración.

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 enumeración tiene un tipo entero correspondiente denominado tipo subyacente del tipo de enumeración. Este tipo subyacente podrá representar todos los valores del enumerador definidos en la enumeración. Si el enum_base está presente, declara explícitamente el tipo subyacente. El tipo subyacente debe ser uno de los tipos enteros (§8.3.6) distintos de char. El tipo subyacente puede especificarse mediante (integral_type§8.3.5) o un integral_type_name. Se integral_type_name resuelve de la misma manera que type_name (§7.8.1), incluida la posibilidad de tener en cuenta las directivas using (§14.5).

Nota: El char tipo no se puede usar como un tipo subyacente, ya sea por palabra clave o a través de .integral_type_name nota final

Una declaración de enumeración que no declara explícitamente un tipo subyacente tiene un tipo subyacente de int.

Ejemplo: El ejemplo

enum Color : long
{
    Red,
    Green,
    Blue
}

declara una enumeración con un tipo subyacente de long.

ejemplo final

Nota: Un desarrollador puede optar por usar un tipo subyacente de long, como en el ejemplo, para habilitar el uso de valores que se encuentran en el intervalo de long , pero no en el intervalo de int, o para conservar esta opción para el futuro. nota final

Nota: C# permite una coma final en un enum_body, al igual que permite una en un array_initializer (§17.7). nota final

Una declaración de enumeración no puede incluir una lista de parámetros de tipo, pero cualquier enumeración anidada dentro de una declaración de clase genérica o una declaración de estructura genérica es una declaración de enumeración genérica, ya que se proporcionarán argumentos de tipo para el tipo contenedor para crear un tipo construido (§8.4).

Modificadores de enumeración 19.3

Un enum_declaration puede incluir opcionalmente una secuencia de modificadores de enumeración:

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

Es un error en tiempo de compilación para que el mismo modificador aparezca varias veces en una declaración de enumeración.

Los modificadores de una declaración de enumeración tienen el mismo significado que los de una declaración de clase (§15.2.2). Sin embargo, los abstractmodificadores , y sealedy static no se permiten en una declaración de enumeración. Las enumeraciones no pueden ser abstractas y no permiten la derivación.

19.4 Miembros de enumeración

El cuerpo de una declaración de tipo de enumeración define cero o más miembros de enumeración, que son las constantes con nombre del tipo de enumeración. No hay dos miembros de enumeración que tengan el mismo nombre.

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

Cada miembro de enumeración tiene un valor constante asociado. El tipo de este valor es el tipo subyacente para la enumeración contenedora. El valor constante de cada miembro de enumeración estará en el intervalo del tipo subyacente de la enumeración.

Ejemplo: El ejemplo

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

produce un error en tiempo de compilación porque los valores constantes -1, -2y -3 no están en el intervalo del tipo uintentero subyacente .

ejemplo final

Varios miembros de enumeración pueden compartir el mismo valor asociado.

Ejemplo: El ejemplo

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

muestra una enumeración en la que dos miembros de enumeración (Blue y Max) tienen el mismo valor asociado.

ejemplo final

El valor asociado de un miembro de enumeración se asigna implícita o explícitamente. Si la declaración del miembro de enumeración tiene un inicializador constant_expression , el valor de esa expresión constante, convertido implícitamente al tipo subyacente de la enumeración, es el valor asociado del miembro de enumeración. Si la declaración del miembro de enumeración no tiene inicializador, su valor asociado se establece implícitamente, como se indica a continuación:

  • Si el miembro de enumeración es el primer miembro de enumeración declarado en el tipo de enumeración, su valor asociado es cero.
  • De lo contrario, el valor asociado del miembro de enumeración se obtiene aumentando el valor asociado del miembro de enumeración de texto anterior por uno. Este valor aumentado estará dentro del intervalo de valores que se pueden representar mediante el tipo subyacente; de lo contrario, se produce un error en tiempo de compilación.

Ejemplo: El ejemplo

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 los nombres de miembro de enumeración y sus valores asociados. La salida es la siguiente:

Red = 0
Green = 10
Blue = 11

por los siguientes motivos:

  • Al miembro Red de enumeración se le asigna automáticamente el valor cero (ya que no tiene inicializador y es el primer miembro de enumeración);
  • el miembro Green de enumeración recibe explícitamente el valor 10;
  • y al miembro Blue de enumeración se le asigna automáticamente el valor uno mayor que el miembro que lo precede textualmente.

ejemplo final

El valor asociado de un miembro de enumeración no utilizará, directa o indirectamente, el valor de su propio miembro de enumeración asociado. Aparte de esta restricción de circularidad, los inicializadores de miembros de enumeración pueden hacer referencia libremente a otros inicializadores de miembro de enumeración, independientemente de su posición textual. Dentro de un inicializador de miembro de enumeración, los valores de otros miembros de enumeración siempre se tratan como tener el tipo de su tipo subyacente, por lo que las conversiones no son necesarias al hacer referencia a otros miembros de enumeración.

Ejemplo: El ejemplo

enum Circular
{
    A = B,
    B
}

produce un error en tiempo de compilación porque las declaraciones de A y B son circulares. A depende explícitamente B de y B depende implícitamente A .

ejemplo final

Los miembros de enumeración se denominan y tienen como ámbito exactamente análogos a los campos dentro de las clases. El ámbito de un miembro de enumeración es el cuerpo de su tipo de enumeración contenedor. Dentro de ese ámbito, se puede hacer referencia a los miembros de enumeración por su nombre simple. A partir del resto del código, el nombre de un miembro de enumeración se calificará con el nombre de su tipo de enumeración. Los miembros de enumeración no tienen ninguna accesibilidad declarada: se puede acceder a un miembro de enumeración si se puede acceder a su tipo de enumeración contenedora.

19.5 El tipo System.Enum

El tipo System.Enum es la clase base abstracta de todos los tipos de enumeración (es distinto y diferente del tipo subyacente del tipo de enumeración) y los miembros heredados de System.Enum están disponibles en cualquier tipo de enumeración. Existe una conversión boxing (§10.2.9) desde cualquier tipo de enumeración a System.Enumy existe una conversión de unboxing (§10.3.7) de System.Enum a cualquier tipo de enumeración.

Tenga en cuenta que System.Enum no es un enum_type. En su lugar, es un class_type del que se derivan todos los enum_type. El tipo System.Enum hereda del tipo System.ValueType (§8.3.2), que, a su vez, hereda del tipo object. En tiempo de ejecución, un valor de tipo System.Enum puede ser null o una referencia a un valor boxed de cualquier tipo de enumeración.

19.6 Valores y operaciones de enumeración

Cada tipo de enumeración define un tipo distinto; Se requiere una conversión de enumeración explícita (§10.3.3) para convertir entre un tipo de enumeración y un tipo entero, o entre dos tipos de enumeración. El conjunto de valores del tipo de enumeración es el mismo que el conjunto de valores del tipo subyacente y no está restringido a los valores de las constantes con nombre. Cualquier valor del tipo subyacente de una enumeración se puede convertir al tipo de enumeración y es un valor válido distinto de ese tipo de enumeración.

Los miembros de enumeración tienen el tipo de su tipo de enumeración contenedor (excepto dentro de otros inicializadores de miembro de enumeración: consulte §19.4). El valor de un miembro de enumeración declarado en el tipo E de enumeración con el valor v asociado es (E)v.

Los operadores siguientes se pueden usar en valores de tipos de enumeración:

Cada tipo de enumeración deriva automáticamente de la clase System.Enum (que, a su vez, deriva de System.ValueType y object). Por lo tanto, los métodos heredados y las propiedades de esta clase se pueden usar en valores de un tipo de enumeración.