Después de depurar un problema particularmente complicado en VB.NET que implica el orden en el que se inicializan las variables de instancia, descubrí que hay una discrepancia de ruptura entre el comportamiento que esperaba de C# y el comportamiento real en VB.NET.¿Se puede obligar a VB.NET a inicializar variables de instancia ANTES de invocar el constructor de tipo base?
Nota bene: Esta pregunta se refiere a una ligera discrepancia en los comportamientos de VB.NET y C#. Si usted es un fanático del lenguaje que no puede proporcionar una respuesta que no sea "es por eso que debe usar C#, noob", no hay nada para que usted vea aquí; amablemente muévete.
Específicamente, esperaba el comportamiento esbozado por el C# Language Specification (énfasis añadido):
Cuando un constructor de instancias no tiene inicializador constructor, o tiene un inicializador constructor de la forma
base(...)
, que constructor realiza implícitamente las inicializaciones especificadas por los inicializadores de variables de los campos de instancia declarados en su clase. Esto corresponde a una secuencia de asignaciones que se ejecutan inmediatamente después de la entrada al constructor y antes de la invocación implícita del constructor de la clase base directa. Los inicializadores de variable se ejecutan en el orden textual en el que aparecen en la declaración de clase.
contraste que con la parte de la especificación del lenguaje VB.NET en relación Instance Constructors, que dice (el subrayado es nuestro):
Cuando la primera declaración de un constructor es de la forma
MyBase.New(...)
, el constructor realiza implícitamente la inicializaciones especificadas por los inicializadores variables de las variables de instancia declaradas en el tipo. Esto corresponde a una secuencia de asignaciones que se ejecutan inmediatamente después de invocar el constructor de tipo base directo. Tal ordenamiento asegura que todas las variables de instancia base sean inicializadas por sus inicializadores variables antes de que se ejecuten las sentencias que tienen acceso a la instancia.
La discrepancia aquí es inmediatamente obvia. C# inicializa las variables de nivel de clase antes de llamando al constructor base. VB.NET hace exactamente lo contrario, al parecer prefiere llamar al constructor base antes de estableciendo los valores de los campos de instancia.
Si quiere ver algún código, this related question proporciona un ejemplo más concreto del comportamiento divergente. Desafortunadamente, no proporciona ninguna pista sobre cómo se puede obligar a VB.NET a seguir el modelo establecido por C#.
Estoy menos interesado en por qué los diseñadores de los dos idiomas eligieron enfoques tan divergentes que en posibles soluciones para el problema. En definitiva, mi pregunta es la siguiente: ¿Hay alguna forma de que pueda escribir o estructurar mi código en VB.NET para forzar las variables de instancia que se inicializarán antes de el constructor del tipo base se llama, como es el comportamiento estándar en C# ?
No creo que sea posible cambiar esto, y el compilador de VB luchará contra cualquier intento de hacerlo. Si confía en tal comportamiento, generalmente es una indicación de problemas en otras partes de su código. Ha habido consejos contra llamar a los miembros virtuales dentro de los constructores durante mucho tiempo (como en el código de ejemplo en la otra pregunta) –
@Damien: tiene razón acerca de que es una mala práctica llamar miembros virtuales dentro de los constructores. Lamentablemente, esa decisión no fue mía. Estoy creando una subclase de un tipo proporcionado por el Framework al mismo tiempo que anulo uno de sus métodos virtuales. Estoy bastante seguro de que los problemas se encuentran fuera de mi código, y lo único que se me ocurre para solucionar esto es gritar "feo truco" para mí. –
vea también http://stackoverflow.com/q/12585555/185593 – serhio