variable utiliza sintaxis reservada que programacion para palabra negativo long example caracteristicas c# compiler-errors

c# - utiliza - ¿Por qué no puedo declarar una enumeración heredada de un byte pero puedo de un byte?



palabra reservada long en c (6)

Si declaro una enumeración como esta ...

public enum MyEnum : byte { Val1, Val2 }

... esta funcionando.

Si declaro una enumeración como esta ...

public enum MyEnum : System.Byte { Val1, Val2 }

... no funciona. El compilador lanza:

error CS1008: tipo byte, sbyte, short, ushort, int, uint, long o ulong esperado

Como byte es un alias para el tipo real, System.Byte , ¿por qué no puedo usar la segunda declaración?


Solo para información:

Con el nuevo compilador de Roslyn este código.

enum SomeEnum : System.Int32 { None, Some }

es válido, por lo tanto, ahora para los tipos de base de enumeración se pueden usar no solo los alias, sino los tipos completos.

Ejemplo en dotnetfiddle, donde puede seleccionar el compilador: https://dotnetfiddle.net/oXyAgV


Aquí está la respuesta, al menos parcialmente, desde MSDN :

Cada tipo de enumeración tiene un tipo subyacente, que puede ser cualquier tipo integral, excepto char. El tipo subyacente predeterminado de elementos de enumeración es int. Para declarar una enumeración de otro tipo integral, como un byte, use dos puntos después del identificador seguido del tipo, como se muestra en el siguiente ejemplo.

Días de copia: byte {Sat = 1, Sun, Mon, Tue, Wed, Thu, Fri};

Los tipos aprobados para una enumeración son byte, sbyte, short, ushort, int, uint, long o ulong.


Bueno, es de acuerdo a la especificación (§14.1). La gramática especifica que la producción de enum-declaration es

enum-declaration: attributes_opt enum-modifiers_opt enum identifier enum-base_opt enum-body ;_opt

dónde

enum-base es

:integral-type

y

integral-type: sbyte byte short ushort int uint long ulong char

En cuanto al por qué la especificación es de esta manera, no está claro.

Tenga en cuenta que char aparece como un terminal para integral-type pero la especificación establece explícitamente que

Tenga en cuenta que char no se puede utilizar como un tipo subyacente.

Por cierto, realmente creo que la mejor práctica aquí es usar los alias. Solo uso el nombre .NET en lugar de la palabra clave C # para estos tipos primitivos (y string ) cuando quiero invocar un método estático. Asi que

Int32.TryParse

en lugar de

int.TryParse.

De lo contrario, digo, por ejemplo, typeof(int) y no typeof(Int32) .


Hay una serie de preguntas planteadas aquí.

¿Por qué no puedo declarar una enumeración heredada de un byte pero puedo de un byte?

Como han dicho otros, eso es lo que dice la especificación.

Las notas del comité de diseño de idiomas no justifican esta decisión. Las notas de junio de 2000 dicen

Las palabras clave para los tipos predefinidos (p. Ej., Int) y sus nombres de tipo correspondientes (p. Ej., Int32) se pueden utilizar indistintamente, pero no de forma total. Discutimos si queríamos hacer algún cambio en esta área. Nosotros no hicimos

Aquí está la lista de lugares donde no son intercambiables.

  • "int" se puede utilizar como un tipo subyacente para enums; Int32 no puede.
  • Las declaraciones de alias no pueden usar palabras clave.

Algunas reflexiones mías sobre el tema:

Lo primero que viene a la mente es que cada vez que le da a un usuario una opción, le da la oportunidad de escribir un error, y cada vez que le da la oportunidad de escribir un error, tiene que crear un mensaje de error. Si permitimos "enum X: Byte", daremos un mensaje de error razonable cuando el usuario haya borrado accidentalmente el "uso del sistema". Podemos evitar esa posible confusión y todos los costos de desarrollar y probar una heurística de informe de errores simplemente no permitiendo la elección en primer lugar.

Lo segundo que se me viene a la mente es que el tipo subyacente de una enumeración se refiere fundamentalmente al mecanismo de la enumeración, no a su significado . Por lo tanto, parece plausible que la cláusula de tipo subyacente se limite a cosas que no requieren un análisis semántico; Sabemos que el tipo subyacente es uno de los ocho tipos posibles, por lo que vamos a hacer que el usuario elija uno de esos ocho tipos sin ambigüedades.

Lo tercero que me viene a la mente es que el análisis de errores se puede realizar durante el análisis sintáctico en lugar del análisis semántico. Cuanto antes se detecte el error, mejor.

ACTUALIZACIÓN: Acabo de preguntar a una de las personas que estaba en la sala ese día si me faltó algo en mis reflexiones y dijo que sí, lo pensaron y decidieron que hacer el análisis completo era trabajo para el desarrollo, Equipo de prueba y mantenimiento, trabajo en el que el usuario no compró nada de valor. (También señaló que tenían argumentos similares sobre System.Void. ¿Debería ser legal decir "System.Void public static estático (string [] args)", por ejemplo? Una vez más, decidieron que esto no agregaba valor para los usuarios, pero sí agregar ambigüedad potencial y trabajar para el equipo.)

¿Por qué "char" no es un tipo subyacente legal?

Una vez más, eso es lo que dice la especificación. Nuevamente, las notas de diseño de idiomas de octubre de 1999 no ayudan a determinar por qué:

Los tipos integrales sin firmar se pueden usar como tipos subyacentes para enumeraciones. El único tipo integral que no se puede utilizar es char.

Una vez más, podemos adivinar. Mi conjetura sería que las enumeraciones están destinadas a ser números extravagantes. Los caracteres en la práctica son enteros como un detalle de implementación, pero lógicamente no son números , son caracteres . Queremos poder realizar operaciones en enumeraciones como las marcas de suma, "or-ing" y "and-ing", etc. La especificación es clara de que estas operaciones se realizan como si se estuvieran realizando en el tipo subyacente. El tipo char, que no es lógicamente un número, no define todos los operadores que pueda desear. Y, por último, si desea un valor de enumeración de dos bytes, entonces ya tiene corto y corto a su disposición.

Una pregunta relacionada de un correo electrónico sobre esta pregunta:

Una lectura cuidadosa de la especificación de la gramática dice que ''char'' es gramaticalmente un tipo subyacente legal, pero el párrafo del texto explicativo después de la gramática dice que ''char'' no es un tipo subyacente legal. ¿Es la especificación inconsistente?

Sí. No voy a perder el sueño por eso. Si te hace sentir mejor, imagina que la línea gramatical que dice

enum-base : tipo integral

en cambio lee

enum-base : tipo integral (pero no char )


La respuesta más simple es "así es como se especifica". (Está en la sección 14.1 de la especificación C # 4. La numeración puede variar para otras versiones).

La especificación no da ninguna razón particular para este 1 , pero podría decirse que es más fácil describir los nombres de alias de tipo integrales (que son todas palabras clave) que decir que puede ser cualquier tipo que se resuelva (mediante otro alias de tipo, como el using directivas) a uno de un conjunto particular.

¿Tienes alguna razón para querer usar System.Byte lugar?

1 La especificación C # 4 anotada tiene una anotación en esta sección ... pero fue escrita por mí, y solo señala que este es uno de los pocos lugares en la especificación donde realmente no puede reemplazar los alias con el tipo normal nombres Así que no es muy útil para esta pregunta :)


Parece que no acepta nombres de tipo reales, sino solo palabras clave de idioma .