example - remarks c#
¿Por qué compilaría esto? (5)
Creé una "const" para un valor previamente explícitamente establecido varias veces en mi código:
private static readonly int QUARTER_HOUR_COUNT = 96;
Cuando hice una búsqueda y reemplazo de 96 para QUARTER_HOUR_COUNT, también reemplazé la declaración inadvertidamente, por lo que se convirtió en:
private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;
... sin embargo, se compiló. Pensaría que no lo permitiría. ¿Por qué fue aceptado por el compilador como una declaración válida?
Pensaría que no lo permitiría. ¿Por qué fue aceptado por el compilador como una declaración válida?
Presumiblemente porque la especificación del lenguaje lo permite. ¿Tiene una regla específica en la especificación de lenguaje que cree que la prohíbe?
Si su pregunta es realmente "¿por qué la especificación del lenguaje no lo prohíbe?", Sospecho que es porque probablemente sea bastante difícil asegurarse de que solo prohíba las cosas que realmente desea prohibir, mientras que en realidad prohíbe todas esas cosas.
Podría argumentar que para casos simples de asignación directamente a sí mismo, sería bueno tener un caso especial en la especificación del idioma, pero introduciría complejidad en el idioma para un beneficio relativamente pequeño.
Tenga en cuenta que incluso si no recibió un error , esperaría que recibiera una advertencia, algo como esto:
Test.cs (3,33): advertencia CS1717: asignación realizada a la misma variable; ¿Querías asignar algo más?
También tenga en cuenta que si lo convierte en una const
lugar de solo una variable de solo lectura estática, entonces obtiene un error en tiempo de compilación:
Test.cs (3,23): error CS0110: la evaluación del valor constante para ''Program.QUARTER_HOUR_COUNT'' implica una definición circular
También tenga en cuenta que según las convenciones de nomenclatura de .NET, esto debería llamarse QuarterHourCount
, en lugar de tener un SHOUTY_NAME.
Como otros tienen valores implícitos, los tipos 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 predeterminado para cualquier tipo así:
int i = default(int);
O más generalmente:
T t = default(T);
Tenga en cuenta que para los tipos de referencia el valor predeterminado será null
, solo los tipos de valor tendrán valores predeterminados.
El código IL generado por el código es este:
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 predeterminado de QUARTER_HOUR_COUNT es 0, el 0 se asigna a QUARTER_HOUR_COUNT
Porque el compilador romperá esta línea:
private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;
Básicamente en el equivalente de IL de:
private static readonly int QUARTER_HOUR_COUNT;
QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;
Y, obviamente, eso también se desglosará más, pero lo anterior debería ser suficiente para ilustrar mi punto.
Así que técnicamente existirá con un valor predeterminado de cero en el momento en que se use.
Porque la variable se inicializó como 0 y luego se configuró a sí misma.
Mi conjetura sería que estaría haciendo un nuevo Int () antes de configurarse a sí mismo, lo que lo inicializaría a cero.