2012-08-15 1 views
28

he creado un "const" para un valor previamente declaró explícitamente varias veces en mi código:¿Por qué esta compilación?

private static readonly int QUARTER_HOUR_COUNT = 96; 

Cuando hice una búsqueda y reemplazo de 96 para QUARTER_HOUR_COUNT, que sin darse cuenta también reemplazó la declaración, por lo que se convirtió en:

private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT; 

... pero compiló. Yo pensaría que eso no lo permitiría. ¿Por qué fue aceptado por el compilador como una declaración válida?

+0

Porque es estática! – canon

+0

¡Guau! Eso es seguro comportamiento sorprendente. – leppie

+0

porque hay un número infinito de maneras de hacerlo mal. – Jodrell

Respuesta

23

I would think that it would disallow that. Why was it accepted by the compiler as a valid declaration?

Presumiblemente porque la especificación del lenguaje lo permite. ¿Tiene una regla específica en la especificación del lenguaje que cree que lo prohíbe?

Si su pregunta es realmente "¿por qué no la especificación del lenguaje prohíbe esto" - Sospecho que es porque es probablemente muy duro para asegurarse de que única prohíben cosas que realmente quiere prohibir, mientras que en realidad prohibir todas esas cosas .

Se podría argumentar que para simples casos de asignación directa de nuevo a sí mismo, sería bueno tener un caso especial en la especificación del lenguaje, pero sería introducir una complejidad en el idioma para relativamente poco beneficio.

Tenga en cuenta que incluso si usted no recibió un error, yo esperaría que usted pueda obtener una advertencia - algo como esto:

Test.cs(3,33): warning CS1717: Assignment made to same variable; did you mean to assign something else?

También tenga en cuenta que si se convierten en un lugar de const sólo una variable de sólo lectura estática, entonces se hace conseguir un error de compilación:

Test.cs(3,23): error CS0110: The evaluation of the constant value for 'Program.QUARTER_HOUR_COUNT' involves a circular definition

también tenga en cuenta que por las convenciones de nomenclatura de .NET, esto debería ser llamado QuarterHourCount, en lugar de tener un SHOUTY_NAME.

+1

Uso de la variable no asignada, pensé. – leppie

+3

@leppie: No para campos estáticos en un inicializador de campo estático. El término "variable no asignada" es irrelevante para los campos estáticos, que no tienen ningún concepto de asignación definida. –

+0

En realidad existe, se inicializan en el orden en que se definen. Este IMO rompe esa regla. – leppie

5

Porque la variable se inicializó como 0 y luego se configuró a sí misma.

Supongo que estaría haciendo un nuevo Int() antes de establecerse a sí mismo que lo inicializaría a cero.

4

Debido a que el compilador romper esta línea de abajo:

private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT; 

Básicamente en el equivalente de IL:

private static readonly int QUARTER_HOUR_COUNT; 
QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT; 

Y entonces, evidentemente, que obtendrá descompone mucho más también, pero lo anterior debe es suficiente para ilustrar mi punto.

Así que técnicamente existirá con un valor predeterminado de cero en el momento en que se usa.

0

Como otros tienen tipos de valores implícitos como int tienen un valor predeterminado por lo que declarar una variable sin inicializarla explícitamente significa que todavía tiene un valor.

Puede averiguar el valor por defecto para cualquier tipo de este modo:

int i = default(int); 

o más en general:

T t = default(T); 

Tenga en cuenta que para este tipo de referencia el valor por defecto será null, sólo los tipos de valor tener valores predeterminados

6

El código IL generada por el código es el siguiente:

IL_0007: ldsfld  int32 Example.Quat::QUARTER_HOUR_COUNT//Load the value of a static field on the stack 
IL_000c: stsfld  int32 Example.Quat::QUARTER_HOUR_COUNT// Store the value from the stack in the static field 

Dado que el valor por defecto de QUARTER_HOUR_COUNT es 0, el 0 se asigna a QUARTER_HOUR_COUNT

Cuestiones relacionadas