c# - parse - ¿Por qué las enumeraciones requieren un molde explícito para el tipo int?
get enum keys c# (7)
¿No sería más intuitivo si estuviera implícito, por ejemplo, cuando tienes un método de nivel superior como:
De hecho, creo que no. En este caso, estás tratando de usar un Enum en un caso extremo.
Sin embargo, si las enumeraciones se convirtieran implícitamente en valores enteros, esto reduciría drásticamente su efectividad. Al forzar una conversión int explícitamente, el compilador trata a enum como un tipo especial, una de muchas opciones, no como un entero. Esto demuestra más claramente la intención de la enumeración, y reduce la posibilidad de errores del programador (es decir, la asignación de valores que no están definidos en la enumeración a una variable enum, etc.).
Personalmente me alegro de que enum en C # sea más que (efectivamente) un valor int constante.
No hay pérdida de datos al hacer esto, ¿cuál es la razón para tener que lanzar explícitamente enumeraciones a ints?
¿No sería más intuitivo si estuviera implícito, por ejemplo, cuando tienes un método de nivel superior como:
PerformOperation ( OperationType.Silent type )
donde PerformOperation
llama a un método envuelto C ++ que está expuesto como tal:
_unmanaged_perform_operation ( int operation_type )
¿Por qué dices que no hay pérdida de datos? No todas las enumeraciones son ints, después de todo. Deben ser de tipo entero, pero eso puede significar byte, ulong, etc.
Como caso de esquina, el literal 0 es implícito, pero; ¿Cuál sería tu caso de uso aquí?
Es bastante raro que necesite hacer esto, por lo general, importación de datos, etc. Un lanzamiento no operativo ocasional tiene mucho sentido para mí y evita errores accidentales.
Esa es la forma en que C # funciona ...
Si Enum hubiera heredado de int, entonces esto debería ser posible. Enum no hereda de int, y por lo tanto, se requiere un molde.
La única forma de clases de conversión implícitas es si heredan.
Hay dos usos principales e inconsistentes de enumeraciones:
enum Medals
{ Gold, Silver, Bronze }
[Flags]
enum FilePermissionFlags
{
CanRead = 0x01,
CanWrite = 0x02,
CanDelete = 0x04
}
En el primer caso, no tiene sentido tratar estas cosas como números. El hecho de que se almacenan como enteros es un detalle de implementación. No puede lógicamente agregar, restar, multiplicar o dividir Oro, Plata y Bronce.
En el segundo caso, tampoco tiene sentido tratar estas cosas como números. No puede sumar, restar, multiplicar o dividir. Las únicas operaciones sensatas son operaciones bit a bit.
Los enumerados son números pésimos, por lo que no debería poder tratarlos como números accidentalmente.
Porque las enumeraciones no tienen que estar basadas en int
:
La palabra clave enum se usa para declarar una enumeración, un tipo distinto que consiste en un conjunto de constantes con nombre llamado lista del enumerador. Cada tipo de enumeración tiene un tipo subyacente, que puede ser de cualquier tipo, excepto char.
Entonces puedes hacer algo como esto:
enum Something :long { valueX = 0, valueY = 2147483648L }
Como otros han dicho, es imposible cambiar el elenco requerido de EnumType
a int
. Sin embargo, hay varias soluciones. Por ejemplo, tengo varias enumeraciones que se refieren a cosas similares, y quería poder asignar cualquiera de ellas a una variable. Entonces fui con:
public ValueType State {
get {
return state;
}
set {
state = (int)value;
}
}
y así, podría decir tanto playerObject.animator.State = Player.STANDING
como monsterObject.animator.State = Monster.DROOLING
, implícitamente tan lejos como la clase llamante podría decir.
Además, sí, hay una razón legítima por la que tengo que tratar los valores enum como números.
Creo que la respuesta a "¿Por qué las enumeraciones requieren un molde explícito para el tipo int?" es que las enumeraciones fuertemente tipadas según C # son una defensa útil contra errores de programación comunes.
Imagine que tengo una aplicación de gestión de pintura, basada en dos enumeraciones:
enum Textures { Gloss, Satin, Matt };
enum Colors { White, Green, Red, Blue, Brown };
Y un método de pintura de habitaciones como este:
private void PaintRoom (Textures texture, Colors color)
En un lenguaje con fuerte enum escribiendo como en C #, un comando como este:
// nonsensical attempt to have texture=White and color=Matt
PaintRoom(Colors.White, Textures.Matt);
... generaría un error en tiempo de compilación (no se puede poner color en donde se espera una textura y viceversa). Pero en los idiomas en los que las enumeraciones no están fuertemente tipadas y / o puede haber una conversión implícita (incluidos C y C ++), tanto nuestros Colors
como nuestras Textures
pueden tratarse como int
, por lo que podemos emitir una PaintRoom(Colors.White, Textures.Matt)
y se compilará bien, pero terminamos con una habitación pintada de rojo brillante (0, 2) en lugar del blanco mate (2, 0) que pretendíamos y el código en un vistazo rápido parece decir.
Así que las enumeraciones fuertemente tipadas son, en su mayoría, algo bueno, para evitar que personas coloquen accidentalmente enums en lugares para los que no estaban destinados. Y cuando alguien realmente quiere su enumeración como int
, C # obliga al codificador a dejar en claro su intención al insistir en una conversión explícita.