Extendiendo La respuesta de la marca, la inicialización de la variable local también está relacionada con el proceso de verificación .
La CLI requiere que en cualquier código verificable (es decir, módulos que no pidieron explícitamente omitir el proceso de verificación utilizando la propiedad SkipVerfication del atributo SecurityPermission), todas las variables locales se deben inicializar antes de su uso. De lo contrario, se generará un VerficationException.
Más interesante aún, es que el compilador agrega automáticamente el indicador .locals init
en cada método que utiliza variables locales. Este indicador hace que el compilador JIT genere código que inicializa todas las variables locales a sus valores predeterminados. Es decir, aunque ya los haya inicializado en su propio código, el JIT cumplirá con el indicador .locals init
y generará el código de inicialización adecuado. Esta "inicialización duplicada" no afecta el rendimiento ya que en las configuraciones que permiten optimizaciones, el compilador JIT detectará la duplicación y la tratará efectivamente como "código muerto" (la rutina de inicialización generada automáticamente no aparecerá en las instrucciones del ensamblador generado).
Según Microsoft (también, respaldado por Eric Lippert en respuesta a una pregunta en su blog), en la mayoría de las ocasiones, cuando los programadores no inicializan su variable local, no lo hacen porque transmiten en el entorno subyacente para inicializar su variable a sus valores predeterminados, pero solo porque se "olvidó", causando errores lógicos a veces ilusorios.
Para reducir la probabilidad de que aparezcan errores de esta naturaleza en el código C#, el compilador aún insiste en que inicializará sus variables locales. Aunque va a agregar el indicador .locals init
al código IL generado.
Una explicación más amplia sobre este tema se puede encontrar aquí: Behind The .locals init Flag
eso es sólo la repetición de la pregunta. ¿Pero por qué? –
@YairHalberstadt que depende de si por "¿por qué?" uno significa la regla o la razón detrás de la regla. Respondí el primero, lo que podría decirse que responde la pregunta; para el segundo: porque para cuando consideramos el encadenamiento de constructores, los métodos virtuales que se invocan durante la construcción y el hecho de que en el nivel IL se pueden llamar constructores base en cualquier punto de la cadena de llamadas, es casi imposible decir nada sensible a la inicialización de campo; igualmente, los campos pueden superponerse, por lo que es aún más importante poner a cero el espacio, por lo que no se requiere init; contraste ... –
@YairHalberstadt variables locales, que tienen una verificación de asignación muy sencilla, donde no inicializado usualmente significa un error, y donde puede omitir el ajuste a cero (aunque el tiempo de ejecución actual nunca lo hace, IIRC). –