2012-01-19 14 views
5

Qualcuno può spiegarmi questo?Perché posso chiamare Form.Close() se non è un metodo statico

In Visual Studio 2010, creare un'app Windows Form VB.net. Aggiungere 2 forme: Form1 e Form2. Nel tipo di evento Load Form1 Form2.Close(). Ora se guardiamo nella definizione del metodo, Close() non è un metodo statico (condiviso). Quindi, come è possibile compilare o lavorare in fase di esecuzione.

Inoltre, fare la stessa cosa in C# e Form2.Close(); non si compila

Cosa sta succedendo? Perché questo è possibile in VB.net e cosa sta realmente accadendo quando viene eseguita quella riga di codice?

+2

Questo è ciò che accade quando Microsoft mette gli sviluppatori 'MS Access' a carico di' VB.NET' per renderlo più attraente per 'VB6'/'Folla VBA'. Segue il disastro ... – ja72

+0

@ ja72 sicuramente il punto di tutto ciò che viene chiamato "VB.x" è avere almeno un certo interesse per gli utenti VB6 e VBA. Detto questo, detestavo questa caratteristica in VB6 e la sua continuazione era un altro motivo per imparare C# invece, quindi suppongo che abbia fatto appello solo ad alcuni dei fan dei VB. –

risposta

6

Hai scoperto un VB.NET-ism chiamato "istanza predefinita".

Il compilatore è in realtà emettendo questo:

My.Forms.Form2.Close(); 

C'è una bella writeup of that feature here:

L'istanza predefinita è un oggetto di quel tipo che il quadro di applicazione VB crea e gestisce per voi.

...

Se si utilizza l'istanza predefinita, allora non è necessario invocare un costruttore in modo esplicito. È sufficiente accedere all'istanza predefinita direttamente tramite l'oggetto My.Forms

+3

Mi piace il ragionamento alla base di questa funzione: * Uno degli obiettivi principali di VB è sempre stato quello di fornire energia, rendendo la programmazione il più semplice possibile per il maggior numero possibile di persone. L'introduzione di istanze di moduli predefinite è a sostegno di tale obiettivo. Molte persone nuove in OOP usano gli oggetti in VB.NET ma non li comprendono veramente correttamente. * Che bel motivo per introdurre singleton impliciti e lazy-instantiated: molte persone nuove a OOP, non conoscono veramente OOP, quindi introduciamo un'altra caratteristica eccezionale. – Groo

+0

Esattamente quello che è successo in questo caso. Il mio cliente capisce a malapena cosa sta facendo e ha pochissima conoscenza di OOP. Eppure è riuscito a fare l'esatto contrario di ciò che stava cercando di fare: ha aumentato la memoria utilizzata dal programma, quando stava cercando di ridurlo. –

5

Il motivo è che VB crea un'istanza automatica del modulo se si fa semplicemente riferimento per nome, il che potrebbe portare a conseguenze impreviste in fase di esecuzione se non viene rilevato.

Non è stata trovata alcuna impostazione per impedire che ciò accada.

Tuttavia, è possibile "interrompere" questo comportamento in fase di compilazione modificando l'ambito del costruttore predefinito da Pubblico ad Amico o rimuovendo il costruttore predefinito e aggiungendo uno che richiede un parametro. Entrambe queste modifiche disabiliteranno i riferimenti di moduli automatici.

1

Si è corretto, non è possibile chiamare Form2.Close(); quando Form2 è solo un tipo di classe. VB.NET, tuttavia, crea una proprietà con lo stesso nome dietro le quinte e pertanto si sta davvero chiamando Close in un'istanza di Form2. Puoi fare lo stesso in C#, se crei manualmente tale proprietà. Sembra una chiamata al metodo statico, ma non lo è.

+1

-1. Questo è un compilatore che emette una chiamata all'istanza predefinita usando il framework dell'applicazione VB. – vcsjones

+0

Dai un'occhiata alle parti generate dell'eseguibile, usando ILSpy o simili. È implementato come una proprietà. – hvd

+0

è una proprietà, è solo un dettaglio di implementazione, dicendo che è una proprietà che non spiega come funziona. È una proprietà di un tipo generato dal compilatore chiamato MyForms. Inoltre; VB.NET non fornisce alcun suggerimento sul fatto che stai chiamando 'Chiudi' su una proprietà. Sembra una chiamata statica. – vcsjones

Problemi correlati