Dopo il debug di un problema particolarmente complicato in VB.NET che coinvolge l'ordine in cui le variabili di istanza sono inizializzate, ho scoperto che c'è una discrepanza di rottura tra il comportamento che mi aspettavo da C# e il comportamento effettivo in VB.NET.È possibile forzare VB.NET a inizializzare le variabili di istanza PRIMA di richiamare il costruttore del tipo di base?
Nota bene: Tale questione riguarda una leggera discrepanza nei comportamenti di VB.NET e C#. Se sei un fanatico della lingua che non è in grado di fornire una risposta diversa da "ecco perché dovresti usare C#, noob", non c'è niente da vedere qui; gentilmente andare avanti
particolare, ho aspettato il comportamento delineata dalla C# Language Specification (enfasi aggiunta):
Quando un costruttore di istanza senza inizializzazione del costruttore, o ha un inizializzatore costruttore del modulo
base(...)
, tale costruttore esegue implicitamente le inizializzazioni specificate dagli inizializzatori di variabile dei campi di istanza dichiarati nella sua classe. Corrisponde a una sequenza di assegnazioni che vengono eseguite immediatamente dopo l'immissione nel costruttore e prima dell'invocazione implicita del costruttore della classe base diretta. Gli inizializzatori variabili vengono eseguiti nell'ordine testuale in cui appaiono nella dichiarazione della classe.
Contrasto che, con la porzione di VB.NET Language Specification riguardante Instance Constructors, che dice (enfasi aggiunta):
Quando prima dichiarazione di un costruttore ha la forma
MyBase.New(...)
, il costruttore esegue implicitamente la inizializzazioni specificate dagli inizializzatori variabili delle variabili di istanza dichiarate nel tipo. Corrisponde a una sequenza di assegnazioni che vengono eseguite immediatamente dopo aver richiamato il costruttore del tipo di base diretta. Tale ordinamento garantisce che tutte le variabili di istanza di base siano inizializzate dai rispettivi inizializzatori di variabili prima che vengano eseguite le istruzioni che hanno accesso all'istanza.
La discrepanza qui è immediatamente ovvia. C# inizializza le variabili a livello di classe prima del chiamando il costruttore di base. VB.NET fa esattamente il contrario, apparentemente preferendo chiamare il costruttore di base prima del impostando i valori dei campi di istanza.
Se si desidera vedere del codice, this related question fornisce un esempio più concreto del comportamento divergente. Sfortunatamente, non fornisce alcun suggerimento su come si possa costringere VB.NET a seguire il modello stabilito da C#.
Sono meno interessato al motivo per cui i progettisti delle due lingue hanno scelto approcci così divergenti rispetto a possibili soluzioni alternative per il problema. In definitiva, la mia domanda è la seguente: Esiste un modo per scrivere o strutturare il mio codice in VB.NET per forzare l'inizializzazione delle variabili di istanza prima del Il costruttore del tipo di base è chiamato, come lo è il comportamento standard in C# ?
Non credo sia possibile modificare questo - e il compilatore VB si batterà contro qualsiasi tentativo di farlo. Se fai affidamento su un comportamento del genere, di solito è un'indicazione di problemi altrove nel tuo codice. È stato consigliato non chiamare i membri virtuali all'interno dei costruttori per un lungo periodo di tempo (come nel codice di esempio nell'altra domanda) –
@Damien: hai ragione a proposito del fatto che è una cattiva pratica chiamare membri virtuali all'interno dei costruttori. Sfortunatamente, quella decisione non era mia. Sto sottoclassi un tipo fornito dal Framework, ignorando anche uno dei suoi metodi virtuali. Sono abbastanza sicuro che i problemi si trovano al di fuori del mio codice, e l'unica cosa che posso pensare di aggiustare questo "brutto scherzo" urla. –
vedi anche http://stackoverflow.com/q/12585555/185593 – serhio