visual variable una tipos studio español enum ejemplo declara datos como clase atributos asignacion c#

variable - enum c# int



¿Por qué el lanzamiento de int al valor enum no válido NO arroja una excepción? (4)

Si tengo una enumeración así:

enum Beer { Bud = 10, Stella = 20, Unknown }

¿Por qué no lanza una excepción al convertir un int que está fuera de estos valores en un tipo de Beer ?

Por ejemplo, el siguiente código no arroja una excepción, emite ''50'' a la consola:

int i = 50; var b = (Beer) i; Console.WriteLine(b.ToString());

Me parece extraño ... ¿alguien puede aclarar?


De la documentation :

A una variable de tipo Días se le puede asignar cualquier valor en el rango del tipo subyacente; los valores no están limitados a las constantes nombradas.


La respuesta corta: los diseñadores de idiomas decidieron diseñar el lenguaje de esta manera.

La respuesta larga: Section 6.2.2: Explicit enumeration conversions de Section 6.2.2: Explicit enumeration conversions de la Especificación del lenguaje C # dice:

Una conversión de enumeración explícita entre dos tipos se procesa tratando cualquier tipo de enumeración participante como el tipo subyacente de ese tipo de enumeración, y luego realizando una conversión numérica implícita o explícita entre los tipos resultantes. Por ejemplo, dado un tipo enum E con y tipo subyacente de int, una conversión de E a byte se procesa como una conversión numérica explícita (§6.2.1) de int a byte, y una conversión de byte a E se procesa como una conversión numérica implícita (§6.1.2) de byte a int.

Básicamente, la enumeración se trata como el tipo subyacente cuando se trata de realizar una operación de conversión. De forma predeterminada, el tipo subyacente de una enumeración es Int32 , lo que significa que la conversión se trata exactamente como una conversión a Int32 . Esto significa que cualquier valor int válido es permitido.

Sospecho que esto se hizo principalmente por motivos de rendimiento. Al hacer que enum un tipo integral simple y permita cualquier conversión de tipo integral, el CLR no necesita hacer todos los controles adicionales. Esto significa que el uso de una enum realmente no tiene ninguna pérdida de rendimiento en comparación con el uso de un número entero, lo que a su vez ayuda a fomentar su uso.


Los mensajes se usan a menudo como indicadores:

[Flags] enum Permission { None = 0x00, Read = 0x01, Write = 0x02, } ... Permission p = Permission.Read | Permission.Write;

El valor de p es el número entero 3, que no es un valor de la enumeración, pero claramente es un valor válido.

Personalmente preferiría haber visto una solución diferente; Preferiría haber tenido la capacidad de hacer tipos enteros de "matriz de bits" y "un conjunto de valores distintos" como dos características de idiomas diferentes en lugar de combinarlas en "enumeración". Pero eso es lo que se les ocurrió a los diseñadores originales de lenguaje y frameworks; como resultado, debemos permitir que los valores no declarados de la enumeración sean valores legales.


Tomado de Confusion con el análisis de un Enum

Esta fue una decisión de parte de las personas que crearon .NET. Una enumeración está respaldada por otro tipo de valor ( int , short , byte , etc.) y, por lo tanto, puede tener cualquier valor que sea válido para esos tipos de valores.

Personalmente, no soy partidario de cómo funciona esto, así que hice una serie de métodos de utilidad:

/// <summary> /// Utility methods for enum values. This static type will fail to initialize /// (throwing a <see cref="TypeInitializationException"/>) if /// you try to provide a value that is not an enum. /// </summary> /// <typeparam name="T">An enum type. </typeparam> public static class EnumUtil<T> where T : struct, IConvertible // Try to get as much of a static check as we can. { // The .NET framework doesn''t provide a compile-checked // way to ensure that a type is an enum, so we have to check when the type // is statically invoked. static EnumUtil() { // Throw Exception on static initialization if the given type isn''t an enum. Require.That(typeof (T).IsEnum, () => typeof(T).FullName + " is not an enum type."); } /// <summary> /// In the .NET Framework, objects can be cast to enum values which are not /// defined for their type. This method provides a simple fail-fast check /// that the enum value is defined, and creates a cast at the same time. /// Cast the given value as the given enum type. /// Throw an exception if the value is not defined for the given enum type. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="enumValue"></param> /// <exception cref="InvalidCastException"> /// If the given value is not a defined value of the enum type. /// </exception> /// <returns></returns> public static T DefinedCast(object enumValue) { if (!System.Enum.IsDefined(typeof(T), enumValue)) throw new InvalidCastException(enumValue + " is not a defined value for enum type " + typeof (T).FullName); return (T) enumValue; } /// <summary> /// /// </summary> /// <param name="enumValue"></param> /// <returns></returns> public static T Parse(string enumValue) { var parsedValue = (T)System.Enum.Parse(typeof (T), enumValue); //Require that the parsed value is defined Require.That(parsedValue.IsDefined(), () => new ArgumentException(string.Format("{0} is not a defined value for enum type {1}", enumValue, typeof(T).FullName))); return parsedValue; } public static bool IsDefined(T enumValue) { return System.Enum.IsDefined(typeof (T), enumValue); } } public static class EnumExtensions { public static bool IsDefined<T>(this T enumValue) where T : struct, IConvertible { return EnumUtil<T>.IsDefined(enumValue); } }

De esta manera, puedo decir:

if(!sEnum.IsDefined()) throw new Exception(...);

... o:

EnumUtil<Stooge>.Parse(s); // throws an exception if s is not a defined value.

Editar

Más allá de la explicación dada anteriormente, debes darte cuenta de que la versión .NET de Enum sigue un patrón inspirado en C más que uno inspirado en Java. Esto hace posible tener enumeraciones de "Bit Flag" que pueden usar patrones binarios para determinar si una "bandera" en particular está activa en un valor enum. Si tuviera que definir todas las combinaciones posibles de banderas (es decir, MondayAndWednesdayAndThursday y MondayAndWednesdayAndThursday , MondayAndWednesdayAndThursday y MondayAndWednesdayAndThursday y MondayAndWednesdayAndThursday ), sería extremadamente tedioso. Por lo tanto, tener la capacidad de usar valores de enum indefinidos puede ser realmente útil. Solo requiere un poco de trabajo adicional cuando desea un comportamiento a prueba de fallas en los tipos de enumeración que no aprovechan este tipo de trucos.