Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium


"Global" variables in vb.net

Posted on 2014-11-03
Medium Priority
Last Modified: 2015-01-21

As you might know from my recent questions, I am converting Access fron-end apps to VB.Net apps (Windows-based currently), and I am mightily confused with the "scope" of variables compared to Access.

Let me explain: in Access, I always have forms with code-behind, usually an app-specific module with all needed logic in subroutines and functions, and a raft of generic routines / functions which are used in many apps. These generic sub's/functions are located in theme-related modules, and they can be called from anywhere: forms and modules.

In VB.net, I took one of my most complex app (not optimal as choice for the "VB.Net newbie" that I am, but it's the one which should be replaced first), and started to convert  the main form, the app-specific module and some of the generic modules. For the moment, I have kept all these in the same project, which is, I know, not how it should be, but gives me time to solve the myriad of other problems I encounter with VB.Net. I have defined the generic modules in Access as public modules in VB.net, and the app-specific module and the form behind-code as public subs within the form class.

But one thing is not clear to me at all: the scope of variables/objects. I don't know how to define (if it is possible) some variables/objects so that they can be accessed by any piece of code in the whole solution. I'm thinking of objects such as datasets, datatables, connections, even such mundane things such as the app's name. In order for variables/objects to be available to a module's subroutine, do they always have to be passed by the caller in the call ? As i have sometimes a hierarchy of calls (A calls B, which in turn calls C and D, the latter calls E), do I have to have a long list of params in every call so that the called routine can access the objects, or is there another way ?

Also I had some weird behavior with input and output variables (results of the called routine) passed in a call if I didn't mention a ByVal or ByRef. Are these absolutly mandatory in the called routines ? In some cases, I do not specify ByRef or ByVal in the called routines, and it works, in other cases it does not.

Can you give me some enlightening, clear pointers or doc about these themes ?

Thanks for help
Question by:bthouin
LVL 45

Assisted Solution

AndyAinscow earned 600 total points
ID: 40419388
This should be relevant:

Basically the scope of variables is pretty much what you are used to experiencing in Access.  Somethings (eg. application name) you can obtain from the app itself - so you don't need to pass them around.

>>A calls B, which in turn calls C and D, the latter calls E
If it is a common pattern of parameters you could consider making a custom class which contains these, so you only have to pass one parameter.  (Note you need to consider the future code maintenance and readability if you did do that).

ps.  Making variables global (or given too much scope) can be a bad design - just because it makes typing parameter lists shorter and easier isn't a good reason why.
LVL 35

Assisted Solution

sarabande earned 600 total points
ID: 40419930
you may define static member variables in a class which make them associated to the class rather than to a single instance of the class. that way these variables would be shared and have global scope.

see http://msdn.microsoft.com/en-us/library/zc2b427x.aspx for sample code.

note, doing so, it doesn't automatically beware of bad design (see comment of Andy). you should use static "shared" members only if they are singleton objects in your application. and the class to member relationship should be "has a" relationship (aggregation), for example class 'Company' "has a" static 'AllEmployees' array.

LVL 40

Accepted Solution

Jacques Bourgeois (James Burger) earned 800 total points
ID: 40420852
The scope of simple variables is the same as it was in Access. I do not see why you are having problems with that.

- Public variables declared in a module are available in all the project.

- Variables declared with Dim (or Private) in a module or a class (a Form is a class) are visible only in that module or class.

- Variables declared in a method (Sub or Function) are visible only in that method.

- A small difference is that variables declared as Public in a class (Form) need to be handled through an instance of that class, that is a variable declared on that class.

- There is also a difference in the way a variable declared in a block (For...Next, While...End While, If...End If) is treated by the compiler. In .NET, it becomes a block variable, visible only in the block.


do they always have to be passed by the caller in the call

No, they don't. But yes, they should, as much as possible.

As Andy stated, Global variables are usually a bad design choice. They take up resources all the time the application is working, even if they are never used. If you have a bug with one of them, you need to look everywhere in the application, while for a local variable, you search for a problem is mostly limited to the method in which they are defined.

It takes getting used to it, but you can do almost everything without any global variable. There are always alternatives in .NET, sometimes hidden however, that you will learn as you go along.

Stuff such as the application name can be defined in the project's Properties window, and then recalled as a constant in the code through Application.ProductName.

Working with custom classes is a way to treat a group of values through only one variable. Dealing with only one variable makes it easy to pass the whole set of values as a parameter to methods that need it instead of having a list of 30 parameters to move around.

A Connection is usually a local variable. You open it, retrieve the data and close it. No need to keep a connection opened, there is a mechanism in the background that manage that for you (see Connection pooling).

Keeping a DataTable or a DataSet in a global variable is a very bad thing. These things use a lot more resources than a Recordset, so create them when needed and update and dump as soon as you are finished. Keeping them for a short time in memory will also help with concurrency (dealing with multiple users on the same data)

I write complex applications, and very rarely use global variables, except for debugging purposes.
Contrary to VBA, ByVal is the default in .NET. So, if you do not specify it, you get a ByVal/

Author Closing Comment

ID: 40561808
Thanks guys for these very helpful comments. Now I will try to implement them :-)

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Recently while returning home from work my wife (another .NET developer) was murmuring something. On further poking she said that she has been assigned a task where she has to serialize and deserialize objects and she is afraid of serialization. Wha…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Integration Management Part 2
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses
Course of the Month10 days, 8 hours left to enroll

572 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question