Dichiarare le variabili globali in Visual Studio 2010 e VB.NET

Come si dichiara una variabile globale in Visual Basic?

Queste variabili devono essere accessibili da tutti i moduli di Visual Basic. So come dichiarare una variabile pubblica per un modulo specifico, ma come faccio a farlo per tutti i moduli del mio progetto?

Non c’è modo di dichiarare le variabili globali come probabilmente le stai immaginando in VB.NET.

Quello che puoi fare (come hanno suggerito alcune delle altre risposte) è dichiarare tutto ciò che vuoi trattare come una variabile globale come variabili statiche invece all’interno di una particolare class:

Public Class GlobalVariables Public Shared UserName As String = "Tim Johnson" Public Shared UserAge As Integer = 39 End Class 

Tuttavia, è necessario qualificare in modo completo tutti i riferimenti a tali variabili ovunque si desideri utilizzarli nel codice. In questo senso, non sono il tipo di variabili globali con le quali potresti avere familiarità con altri linguaggi, perché sono ancora associati ad alcune classi particolari.

Ad esempio, se vuoi visualizzare una finestra di messaggio nel codice del tuo modulo con il nome dell’utente, dovrai fare qualcosa del genere:

 Public Class Form1 : Inherits Form Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load MessageBox.Show("Hello, " & GlobalVariables.UserName) End Sub End Class 

Non è ansible accedere semplicemente alla variabile digitando UserName al di fuori della class in cui è definito, è inoltre necessario specificare il nome della class in cui è definito.

Se la pratica di qualificare in modo completo le tue variabili ti sconvolge o ti sconvolge per qualsiasi motivo, puoi sempre importare la class che contiene le dichiarazioni delle variabili globali (qui, GlobalVariables ) nella parte superiore di ogni file di codice (o anche a livello di progetto, in la finestra delle proprietà del progetto). Quindi, puoi semplicemente fare riferimento alle variabili con il loro nome.

 Imports GlobalVariables 

Nota che questa è esattamente la stessa cosa che il compilatore sta facendo per te dietro le quinte quando dichiari le tue variabili globali in un Module , piuttosto che in una Class . In VB.NET, che offre moduli per scopi retrocompatibili con versioni precedenti di VB, un Module è semplicemente una class statica sigillata (o, in termini VB.NET, Shared NotInheritable Class ). L’IDE consente di chiamare membri dai moduli senza qualificare completamente o importare un riferimento a questi. Anche se decidi di seguire questa strada, vale la pena capire cosa succede dietro le quinte in un linguaggio orientato agli oggetti come VB.NET. Penso che come programmatore, è importante capire cosa sta succedendo e che cosa esattamente i tuoi strumenti stanno facendo per te, anche se decidi di usarli. E per quello che vale, non lo consiglio come una “best practice” perché ritengo che tenda all’oscurità e al codice / design pulito orientato agli oggetti. È molto più probabile che un programmatore C # comprenda il tuo codice se è scritto come mostrato sopra che se lo si inserisce in un modulo e si lascia che il compilatore gestisca tutto.

Nota che come almeno un’altra risposta ha fatto riferimento, VB.NET è un linguaggio completamente orientato agli oggetti. Ciò significa, tra le altre cose, che tutto è un object. Anche le variabili “globali” devono essere definite all’interno di un’istanza di una class perché sono anche oggetti. Ogni volta che senti la necessità di utilizzare variabili globali in un linguaggio orientato agli oggetti, quel segno devi ripensare il tuo design. Se stai semplicemente passando alla programmazione orientata agli oggetti, vale la pena fermarsi e imparare alcuni dei modelli di base prima di trincerarsi ulteriormente nella scrittura del codice.

Più o meno allo stesso modo che hai sempre, con “Moduli” invece di classi e basta usare “Pubblico” invece della vecchia parola chiave “Globale”:

 Public Module Module1 Public Foo As Integer End Module 

Va bene. Alla fine ho trovato ciò che effettivamente funziona per rispondere alla domanda che sembra essere posta;

“Quando ho bisogno di molti moduli e moduli, come posso dichiarare una variabile come pubblica a tutti, in modo che ognuno faccia riferimento alla stessa variabile?”

Sorprendentemente, ho passato molto tempo a cercare sul web questa domanda apparentemente semplice, non trovando altro che la vaghezza che mi ha lasciato ancora degli errori.

Ma grazie al collegamento di Cody Gray ad un esempio , sono stato in grado di discernere una risposta adeguata;


Situazione ; Hai più Moduli e / o Moduli e vuoi fare riferimento a una particolare variabile da tutti o tutti.

“Un” modo che funziona; Su un modulo posizionare il seguente codice (in cui “DefineGlobals” è un nome scelto arbitrariamente);

 Public Module DefineGlobals Public Parts As Integer 'Assembled-particle count Public FirstPrtAff As Long 'Addr into Link List End Module 

E poi in ogni modulo / modulo che necessita di indirizzare quella variabile “Parti”, inserire il seguente codice (come un esempio del modulo “InitForm2”);

 Public Class InitForm2 Private Sub InitForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Parts = Parts + 3 End Sub End Class 

E forse un’altra forma; FormX di class pubblica

 Sub CreateAff() Parts = 1000 End Sub End Class 

Quel tipo di codifica sembra aver funzionato sul mio VB2008 Express e sembra essere tutto necessario al momento (nessun file sconosciuto viene caricato in background) anche se non ho trovato fine alla sorpresa “Oh btw …” dettagli. E sono certo che un maggior grado di standardizzazione sarebbe preferibile, ma il primo compito è semplicemente quello di ottenere qualcosa che funzioni, con o senza standard.

Niente batte esempi esatti e ben formulati, espliciti .

Grazie ancora, Cody

Rendilo statico (condiviso in VB).

 Public Class Form1 Public Shared SomeValue As Integer = 5 End Class 

Le variabili pubbliche sono un odore di codice: prova a riprogettare la tua applicazione in modo che non siano necessarie. La maggior parte dei ragionamenti qui e qui sono applicabili a VB.NET.

Il modo più semplice per avere variabili globali in VB.NET è di creare variabili statiche pubbliche su una class (dichiarare una variabile come Public Shared ).

Una variabile globale potrebbe essere accessibile in tutti i moduli del progetto se si utilizza la parola chiave public shared se si trova in una class. Funzionerà anche se si utilizza la parola chiave “pubblico” se si trova sotto un modulo, ma non è la migliore pratica per molte ragioni.

(… Sì, ripeto un po ‘cosa hanno detto “Cody Gray” e “RBarryYoung”.)

Uno dei problemi è quando si hanno due thread che chiamano la stessa variabile globale allo stesso tempo. Avrai delle sorprese. Potresti avere reazioni inaspettate se non conosci i loro limiti. Dai un’occhiata al post Global Variables in Visual Basic .NET e scarica il progetto di esempio!

piccola osservazione: sto usando i moduli nell’applicazione web (asp.net). Ho bisogno di ricordare che tutto ciò che memorizzo nelle variabili del modulo sono visti da tutti nell’applicazione, leggi il sito web. Non solo nella mia sessione. Se cerco di aggiungere un calcolo nella mia sessione, ho bisogno di creare un array per filtrare i numeri per la mia sessione e per gli altri. I moduli sono un ottimo modo per lavorare ma devono concentrarsi su come usarlo.

Per aiutare contro gli errori: le classi vengono inviate al

CarbageCollector

quando la pagina è finita. I miei moduli rimangono attivi (a patto che l’applicazione non sia terminata o riavviata) e posso riutilizzare i dati al suo interno. Lo uso per salvare i dati che a volte vengono persi a causa del trattamento della sessione da parte di IIS.

Autenticazione modulo IIS

e

IIS_session

non sono sincronizzati, e con il mio modulo tiro indietro i dati che sono andati oltre la scogliera.

Nessuna di queste risposte sembra cambiare nulla per me.

Sto convertendo un vecchio programma Excel in VB 2008. Ovviamente ci sono molti elementi specifici di Excel da modificare, ma qualcosa che sta causando un mal di testa sembra essere l’intero problema “pubblico”.

Ho circa 40 matrici tutte referenziate da circa 20 moduli. Gli array costituiscono le fondamenta dell’intero progetto e sono indirizzati da quasi ogni procedura.

In Excel, ho semplicemente dovuto dichiararli tutti come pubblici. Ha funzionato alla grande Nessun problema. Ma in VB2008, trovo che sia piuttosto un problema. È assurdo pensare che devo passare attraverso migliaia di righe di codice solo per raccontare ogni riferimento in cui è stato dichiarato il pubblico. Ma anche volendo farlo, nessuno degli schemi proposti sembra essere di aiuto.

Sembra che “Pubblico” significhi semplicemente “Pubblico all’interno di questo modulo”. L’aggiunta di “Condivisa” sembra non fare nulla per cambiarlo. Aggiungere il nome del modulo o qualsiasi altra cosa non sembra cambiarlo. Ogni modulo insiste sul fatto che dichiaro tutti gli array (e circa 100 altre variabili fondamentali) all’interno di ciascun modulo (un anticipo apparentemente arretrato). E il bit “Imports” non sembra sapere di cosa sto parlando, “non può essere trovato”.

Devo simpatizzare con l’interrogante. Qualcosa sembra terribilmente sbagliato con tutto questo.

Il primo ragazzo con una class pubblica ha molto più senso. Il ragazzo originale ha più forms e se sono necessarie variabili globali, allora la class globale sarà migliore. Pensa a qualcuno che lo codifica dietro di sé e ha bisogno di usare una variabile globale in una class che hai intellisense, inoltre renderà la codifica una modifica 6 mesi dopo molto più facile.

Anche se ho una scoreggia cerebrale e uso come in un esempio di parti a livello di modulo, allora voglio che le mie parti globali possano fare qualcosa di simile

 Dim Parts as Integer parts = 3 GlobalVariables.parts += Parts '< Not recommended but it works 

Almeno è per questo che vado per la via della class.

Le varie risposte in questo blog sembrano essere definite da SE che promuove la stretta aderenza alle solite regole della programmazione orientata agli oggetti (utilizzare una class pubblica con riferimenti pubblici condivisi (anche statici) e pienamente qualificati, o SE che promuovono l’uso la funzione di compatibilità all’indietro (Modulo) per la quale il compilatore ha ovviamente bisogno di fare la stessa cosa per farlo funzionare.

Come SE con più di 30 anni di esperienza, proporrei le seguenti linee guida:

  1. Se stai scrivendo tutto il nuovo codice (non tentando di convertire un’app legacy) eviti di utilizzare questi moduli del tutto eccetto nel raro caso in cui hai davvero bisogno di avere una variabile statica, perché possono causare conseguenze terribili (e davvero difficili- trovare i bug). (Il codice multithread e multiprocessing richiede semafori attorno a variabili statiche …)

  2. Se stai modificando una piccola applicazione che ha già alcune variabili globali, allora le formuli in modo che non siano oscurate dai moduli, cioè usa le regole standard della programmazione orientata agli oggetti per ricrearle come statiche pubbliche e accedervi per intero qualificazione in modo che altri possano capire cosa sta succedendo.

  3. Se hai una grande applicazione legacy con dozzine o centinaia di variabili globali, usa tutti i moduli per definirli. Non c’è motivo di perdere tempo nel far funzionare l’applicazione, perché probabilmente sei già dietro la 8-ball nel tempo speso in Proprietà, ecc.

Tutto quanto sopra può essere evitato semplicemente dichiarando un valore amico per il runtime sul modulo di partenza.

 Public Class Form1 Friend sharevalue as string = "Boo" 

Quindi accedi a questa variabile da tutti i moduli usando semplicemente Form1.sharevalue

 Public Class Form1 Public Shared SomeValue As Integer = 5 End Class 

La risposta:

 MessageBox.Show("this is the number"&GlobalVariables.SomeValue)